diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..dfdb8b771 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.sh text eol=lf diff --git a/.github/actions/createPostgresqlFlexibleServer/action.yml b/.github/actions/createPostgresqlFlexibleServer/action.yml new file mode 100644 index 000000000..4e88d3da7 --- /dev/null +++ b/.github/actions/createPostgresqlFlexibleServer/action.yml @@ -0,0 +1,62 @@ +name: Create PostgreSQL Flexible Server +description: Create PostgreSQL Flexible Server that allows access from Azure services. +inputs: + dbAdminUser: + description: "Database Admin User" + required: true + dbName: + description: "Database Name" + required: true + dbPassword: + description: "Database Password" + required: true + dbServerName: + description: "Database Server Name" + required: true + location: + description: "Location" + required: true + resourceGroupName: + description: "Resource Group Name" + required: true + +runs: + using: "composite" + steps: + - uses: actions/checkout@v2.3.4 + - name: Set azCliVersion + uses: ./.github/actions/setvars + with: + varFilePath: ./.github/variables/vm-dependencies.env + - name: Set Up Azure Postgresql that allows access from Azure services + id: setup-postgresql + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + echo "Deploy DB with name " ${{ inputs.dbName }} + az postgres flexible-server create \ + --resource-group ${{ inputs.resourceGroupName }} \ + --name ${{ inputs.dbName }} \ + --location ${{ inputs.location }} \ + --admin-user ${{ inputs.dbAdminUser }} \ + --admin-password ${{ inputs.dbPassword }} \ + --version 16 \ + --public-access 0.0.0.0 \ + --tier Burstable \ + --sku-name Standard_B1ms \ + --yes + + az postgres flexible-server db create \ + --resource-group ${{ inputs.resourceGroupName }} \ + --server-name ${{ inputs.dbName }} \ + --database-name ${{ inputs.dbServerName }} + + sleep 1m + echo "Allow Access To Azure Services" + az postgres flexible-server firewall-rule create \ + -g ${{ inputs.resourceGroupName }} \ + -n ${{ inputs.dbName }} \ + -r "AllowAllAzureServices" \ + --start-ip-address "0.0.0.0" \ + --end-ip-address "0.0.0.0" diff --git a/.github/actions/database-parameters/action.yaml b/.github/actions/database-parameters/action.yaml new file mode 100644 index 000000000..53af62005 --- /dev/null +++ b/.github/actions/database-parameters/action.yaml @@ -0,0 +1,143 @@ +name: Get Database parameters +description: Get Database parameters + +inputs: + databaseType: + description: "databaseType" + required: true + uamiId: + description: "uamiId" + required: true + serverHost: + description: "serverHost" + required: true + dbInstanceName: + description: "dbInstanceName" + required: true + dbAdminUser: + description: "dbAdminUser" + required: false + default: "testuser" + databaseName: + description: "databaseName" + required: true + default: "testdb" + +outputs: + enableDB: + description: "enableDB" + value: ${{ steps.database-parameters.outputs.enableDB }} + enablePswlessConnection: + description: "enablePswlessConnection" + value: ${{ steps.database-parameters.outputs.enablePswlessConnection }} + databaseType: + description: "databaseType" + value: ${{ steps.database-parameters.outputs.databaseType }} + dsConnectionURL: + description: "dsConnectionURL" + value: ${{ steps.database-parameters.outputs.dsConnectionURL }} + dbUser: + description: "dbUser" + value: ${{ steps.database-parameters.outputs.dbUser }} + dbIdentity: + description: "dbIdentity" + value: ${{ steps.database-parameters.outputs.dbIdentity }} + +runs: + using: "composite" + steps: + - name: Set up environment variables + shell: bash + id: database-parameters + run: | + enableDB=false + databaseType=sqlserver + dsConnectionURL=jdbc:postgresql://contoso.postgres.database:5432/${{ inputs.databaseName }} + dbUser=contosoDbUser + enablePswlessConnection=false + dbIdentity={} + serverHost=${{ inputs.serverHost }} + uamiId=${{ inputs.uamiId }} + echo "databaseType: ${{ inputs.databaseType }}" + echo "serverHost : $serverHost" + if ${{ inputs.databaseType == 'mssqlserver' }}; then + echo "Using mssqlserver database type" + enableDB=true + databaseType=sqlserver + dsConnectionURL="jdbc:sqlserver://$serverHost:1433;database=${{ inputs.databaseName }}" + dbUser=${{ inputs.dbAdminUser }}@${{ inputs.dbInstanceName }} + elif ${{ inputs.databaseType == 'mssqlserver-passwordless' }}; then + echo "Using mssqlserver-passwordless database type" + enableDB=true + enablePswlessConnection=true + databaseType=sqlserver + dsConnectionURL="jdbc:sqlserver://$serverHost:1433;database=${{ inputs.databaseName }}" + dbUser=${{ inputs.dbAdminUser }}@${{ inputs.dbInstanceName }} + dbIdentity=$(jq -n \ + --arg uamiId "$uamiId" \ + '{ + "type": "UserAssigned", + "userAssignedIdentities": { + ($uamiId): {} + } + }'| jq -c '.') + elif ${{ inputs.databaseType == 'oracle' }}; then + echo "Using oracle database type" + enableDB=true + databaseType=oracle + dsConnectionURL=jdbc:oracle:thin:@${serverHost}:1521/oratest1 + dbUser=${{ inputs.dbAdminUser }} + elif ${{ inputs.databaseType == 'mysql(flexible)' }}; then + echo "Using mysql(flexible) database type" + enableDB=true + databaseType=mysql + dsConnectionURL=jdbc:mysql://$serverHost:3306/${{ inputs.databaseName }}?sslMode=REQUIRED + dbUser=${{ inputs.dbAdminUser }} + elif ${{ inputs.databaseType == 'mysql-passwordless(flexible)' }}; then + echo "Using mysql-passwordless(flexible) database type" + enableDB=true + enablePswlessConnection=true + dbUser=$(basename "$uamiId") + dbIdentity=$(jq -n \ + --arg uamiId "$uamiId" \ + '{ + "type": "UserAssigned", + "userAssignedIdentities": { + ($uamiId): {} + } + }'| jq -c '.' ) + databaseType=mysql + dsConnectionURL=jdbc:mysql://$serverHost:3306/${{ inputs.databaseName }} + elif ${{ inputs.databaseType == 'postgresql(flexible)' }}; then + echo "Using postgresql(flexible) database type" + enableDB=true + databaseType=postgresql + dsConnectionURL="jdbc:postgresql://$serverHost:5432/${{ inputs.databaseName }}" + dbUser=${{ inputs.dbAdminUser }} + elif ${{ inputs.databaseType == 'postgresql-passwordless(flexible)' }}; then + echo "Using postgresql-passwordless(flexible) database type" + enableDB=true + enablePswlessConnection=true + dbUser=$(basename "$uamiId") + dbIdentity=$(jq -n \ + --arg uamiId "$uamiId" \ + '{ + "type": "UserAssigned", + "userAssignedIdentities": { + ($uamiId): {} + } + }'| jq -c '.') + databaseType=postgresql + dsConnectionURL="jdbc:postgresql://$serverHost:5432/${{ inputs.databaseName }}" + fi + + echo "enableDB=$enableDB" >> "$GITHUB_OUTPUT" + echo "enablePswlessConnection=$enablePswlessConnection" >> "$GITHUB_OUTPUT" + echo "databaseType=$databaseType" >> "$GITHUB_OUTPUT" + echo "dsConnectionURL=$dsConnectionURL" >> "$GITHUB_OUTPUT" + echo "dbUser=$dbUser" >> "$GITHUB_OUTPUT" + echo "dbIdentity=$dbIdentity" >> "$GITHUB_OUTPUT" + echo "dsConnectionURL=$dsConnectionURL" + echo "dbUser=$dbUser" + echo "Database parameters set successfully" + diff --git a/.github/actions/database-provision/action.yaml b/.github/actions/database-provision/action.yaml new file mode 100644 index 000000000..582908a84 --- /dev/null +++ b/.github/actions/database-provision/action.yaml @@ -0,0 +1,287 @@ +name: Database provision +description: Database provision + +inputs: + databaseType: + description: "databaseType" + required: true + resourceGroup: + description: "resourceGroup" + required: true + uamiName: + description: "uamiName" + required: true + location: + description: "location" + required: true + dbInstanceName: + description: "dbInstanceName" + required: true + dbPassword: + description: "dbPassword" + required: true + dbAdminUser: + description: "dbAdminUser" + required: false + default: "testuser" + databaseName: + description: "databaseName" + required: true + default: "testdb" + +outputs: + serverHost: + description: "serverHost" + value: ${{ steps.resource_outputs.outputs.serverHost }} + uamiId: + description: "uamiId" + value: ${{ steps.resource_outputs.outputs.uamiId }} + +runs: + using: "composite" + steps: + # 01-Deploy an instance of Azure SQL Database + - name: Echo inputs + shell: bash + run: | + echo "resourceGroup=${{ inputs.resourceGroup }}" + echo "uamiName=${{ inputs.uamiName }}" + echo "location=${{ inputs.location }}" + echo "dbInstanceName=${{ inputs.dbInstanceName }}" + echo "dbAdminUser=${{ inputs.dbAdminUser }}" + echo "databaseName=${{ inputs.databaseName }}" + - name: Deploy an instance of Azure SQL Database + id: deploy-mssqlserver + if: ${{ inputs.databaseType == 'mssqlserver' }} + shell: bash + run: | + az sql server create \ + --resource-group ${{ inputs.resourceGroup }} \ + --name ${{ inputs.dbInstanceName }} \ + --admin-user ${{ inputs.dbAdminUser }} --admin-password ${{ inputs.dbPassword }} \ + --location ${{ inputs.location }} + host=$(az sql server show \ + --resource-group ${{ inputs.resourceGroup }} \ + --name ${{ inputs.dbInstanceName }} \ + --query "fullyQualifiedDomainName" -o tsv) + # Allow Azure services to access + az sql server firewall-rule create \ + --resource-group ${{ inputs.resourceGroup }} \ + --server ${{ inputs.dbInstanceName }} \ + --name "AllowAllAzureIps" --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0 + az sql db create --resource-group ${{ inputs.resourceGroup }} \ + --server ${{ inputs.dbInstanceName }} \ + --name ${{ inputs.databaseName }} + + echo "serverHost=${host}" >> "$GITHUB_ENV" + + - name: Deploy an instance of Azure SQL passwordless Database + id: deploy-mssqlserver-passwordless + if: ${{ inputs.databaseType == 'mssqlserver-passwordless' }} + shell: bash + run: | + # Create a user-assigned managed identity + az identity create --name ${{ inputs.uamiName }} --resource-group ${{ inputs.resourceGroup }} + # Export the resource ID of the user-assigned managed identity as an environment variable + uamiId=$(az identity show --name ${{ inputs.uamiName }} --resource-group ${{ inputs.resourceGroup }} --query id -o tsv) + objectId=$(az identity show --name ${{ inputs.uamiName }} --resource-group ${{ inputs.resourceGroup }} --query principalId -o tsv) + + az sql server create \ + --resource-group ${{ inputs.resourceGroup }} \ + --name ${{ inputs.dbInstanceName }} \ + --admin-user ${{ inputs.dbAdminUser }} \ + --admin-password ${{ inputs.dbPassword }} \ + --assign-identity \ + --external-admin-principal-type Application \ + --external-admin-name ${{ inputs.uamiName }} \ + --external-admin-sid $objectId \ + --location ${{ inputs.location }} + host=$(az sql server show \ + --resource-group ${{ inputs.resourceGroup }} \ + --name ${{ inputs.dbInstanceName }} \ + --query "fullyQualifiedDomainName" -o tsv) + # Allow Azure services to access + az sql server firewall-rule create \ + --resource-group ${{ inputs.resourceGroup }} \ + --server ${{ inputs.dbInstanceName }} \ + --name "AllowAllAzureIps" --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0 + az sql db create --resource-group ${{ inputs.resourceGroup }} \ + --server ${{ inputs.dbInstanceName }} \ + --name ${{ inputs.databaseName }} + + echo "serverHost=${host}" >> "$GITHUB_ENV" + echo "uamiId=${uamiId}" >> "$GITHUB_ENV" + + - name: Deploy an instance of Azure Database for MySQL + id: deploy-mysql + if: ${{ inputs.databaseType == 'mysql(flexible)' }} + shell: bash + run: | + az mysql flexible-server create \ + --resource-group ${{ inputs.resourceGroup }} \ + --name ${{ inputs.dbInstanceName }} \ + --admin-user myadmin \ + --admin-password ${{ inputs.dbPassword }} \ + --sku-name Standard_B1ms \ + --location ${{ inputs.location }} \ + --version 8.0.21 \ + --yes + + # Allow Azure services to access + az mysql flexible-server firewall-rule create \ + --resource-group ${{ inputs.resourceGroup }} \ + --name ${{ inputs.dbInstanceName }} \ + --rule-name "AllowAllAzureIps" \ + --start-ip-address 0.0.0.0 \ + --end-ip-address 0.0.0.0 + # Allow current IP to access MySQL server + currentIp=$(curl -s https://icanhazip.com) + az mysql flexible-server firewall-rule create \ + --resource-group ${{ inputs.resourceGroup }} \ + --name ${{ inputs.dbInstanceName }} \ + --rule-name "AllowCurrentIp" \ + --start-ip-address ${currentIp} \ + --end-ip-address ${currentIp} + host=$(az mysql flexible-server show \ + --resource-group ${{ inputs.resourceGroup }} \ + --name ${{ inputs.dbInstanceName }} \ + --query "fullyQualifiedDomainName" -o tsv) + + wget --no-check-certificate https://dl.cacerts.digicert.com/DigiCertGlobalRootCA.crt.pem + mysql -h $host -u myadmin -p${{ inputs.dbPassword }} --ssl-ca=DigiCertGlobalRootCA.crt.pem << EOF + CREATE DATABASE ${{ inputs.databaseName }}; + CREATE USER '${{ inputs.dbAdminUser }}'@'%' IDENTIFIED BY '${{ inputs.dbPassword }}'; + GRANT ALL PRIVILEGES ON ${{ inputs.databaseName }} . * TO '${{ inputs.dbAdminUser }}'@'%'; + FLUSH PRIVILEGES; + EOF + + echo "serverHost=${host}" >> "$GITHUB_ENV" + + - name: Deploy an instance of Azure Database for MySQL passwordless + id: deploy-mysql-passwordless + if: ${{ inputs.databaseType == 'mysql-passwordless(flexible)' }} + shell: bash + run: | + az mysql flexible-server create \ + --resource-group ${{ inputs.resourceGroup }} \ + --name ${{ inputs.dbInstanceName }} \ + --admin-user myadmin \ + --admin-password ${{ inputs.dbPassword }} \ + --sku-name Standard_B1ms \ + --location ${{ inputs.location }} \ + --version 8.0.21 \ + --yes + + # Allow Azure services to access + az mysql flexible-server firewall-rule create \ + --resource-group ${{ inputs.resourceGroup }} \ + --name ${{ inputs.dbInstanceName }} \ + --rule-name "AllowAllAzureIps" \ + --start-ip-address 0.0.0.0 \ + --end-ip-address 0.0.0.0 + # Allow current IP to access MySQL server + currentIp=$(curl -s https://icanhazip.com) + az mysql flexible-server firewall-rule create \ + --resource-group ${{ inputs.resourceGroup }} \ + --name ${{ inputs.dbInstanceName }} \ + --rule-name "AllowCurrentIp" \ + --start-ip-address ${currentIp} \ + --end-ip-address ${currentIp} + host=$(az mysql flexible-server show \ + --resource-group ${{ inputs.resourceGroup }} \ + --name ${{ inputs.dbInstanceName }} \ + --query "fullyQualifiedDomainName" -o tsv) + + wget --no-check-certificate https://dl.cacerts.digicert.com/DigiCertGlobalRootCA.crt.pem + mysql -h $host -u myadmin -p${{ inputs.dbPassword }} --ssl-ca=DigiCertGlobalRootCA.crt.pem << EOF + CREATE DATABASE ${{ inputs.databaseName }}; + CREATE USER '${{ inputs.dbAdminUser }}'@'%' IDENTIFIED BY '${{ inputs.dbPassword }}'; + GRANT ALL PRIVILEGES ON ${{ inputs.databaseName }} . * TO '${{ inputs.dbAdminUser }}'@'%'; + FLUSH PRIVILEGES; + EOF + + # Create a user-assigned managed identity + az identity create --name ${{ inputs.uamiName }} --resource-group ${{ inputs.resourceGroup }} + # Export the resource ID of the user-assigned managed identity as an environment variable + uamiId=$(az identity show --name ${{ inputs.uamiName }} --resource-group ${{ inputs.resourceGroup }} --query id -o tsv) + objectId=$(az identity show --name ${{ inputs.uamiName }} --resource-group ${{ inputs.resourceGroup }} --query principalId -o tsv) + + az mysql flexible-server ad-admin create \ + --resource-group ${{ inputs.resourceGroup }} \ + --server-name ${{ inputs.dbInstanceName }} \ + --display-name ${{ inputs.uamiName }} \ + --object-id $objectId \ + --identity $uamiId + + echo "serverHost=${host}" >> "$GITHUB_ENV" + echo "uamiId=${uamiId}" >> "$GITHUB_ENV" + + - name: Deploy an instance of Azure Database for PostgreSQL + id: deploy-postgresql + if: ${{ inputs.databaseType == 'postgresql(flexible)' }} + shell: bash + run: | + az postgres flexible-server create \ + --resource-group ${{ inputs.resourceGroup }} \ + --name ${{ inputs.dbInstanceName }} \ + --admin-user ${{ inputs.dbAdminUser }} --admin-password ${{ inputs.dbPassword }} \ + --public-access 0.0.0.0 \ + --location ${{ inputs.location }} \ + --yes + echo "Get the host name of the PostgreSQL server" + host=$(az postgres flexible-server show \ + --resource-group ${{ inputs.resourceGroup }} \ + --name ${{ inputs.dbInstanceName }} \ + --query "fullyQualifiedDomainName" -o tsv) + echo "Create a database in the PostgreSQL server" + az postgres flexible-server db create --resource-group ${{ inputs.resourceGroup }} \ + --server-name ${{ inputs.dbInstanceName }} \ + --database-name ${{ inputs.databaseName }} + + echo "serverHost=${host}" >> "$GITHUB_ENV" + - name: Deploy an instance of Azure Database for PostgreSQL passwordless + if: ${{ inputs.databaseType == 'postgresql-passwordless(flexible)' }} + id: deploy-postgresql-passwordless + shell: bash + run: | + + # Create a user-assigned managed identity + az identity create --name ${{ inputs.uamiName }} --resource-group ${{ inputs.resourceGroup }} + # Export the resource ID of the user-assigned managed identity as an environment variable + uamiId=$(az identity show --name ${{ inputs.uamiName }} --resource-group ${{ inputs.resourceGroup }} --query id -o tsv) + objectId=$(az identity show --name ${{ inputs.uamiName }} --resource-group ${{ inputs.resourceGroup }} --query principalId -o tsv) + + az postgres flexible-server create \ + --microsoft-entra-auth Enabled \ + --resource-group ${{ inputs.resourceGroup }} \ + --name ${{ inputs.dbInstanceName }} \ + --public-access 0.0.0.0 \ + --location ${{ inputs.location }} \ + --yes + echo "Set the user-assigned managed identity as the Microsoft Entra admin for the PostgreSQL server" + sleep 120 # Wait for the server to be ready + az postgres flexible-server microsoft-entra-admin create \ + --resource-group ${{ inputs.resourceGroup }} \ + --server-name ${{ inputs.dbInstanceName }} \ + --display-name ${{ inputs.uamiName }} \ + --object-id $objectId \ + --type ServicePrincipal + echo "Get the host name of the PostgreSQL server" + host=$(az postgres flexible-server show \ + --resource-group ${{ inputs.resourceGroup }} \ + --name ${{ inputs.dbInstanceName }} \ + --query "fullyQualifiedDomainName" -o tsv) + echo "Create a database in the PostgreSQL server" + az postgres flexible-server db create --resource-group ${{ inputs.resourceGroup }} \ + --server-name ${{ inputs.dbInstanceName }} \ + --database-name ${{ inputs.databaseName }} + + echo "serverHost=${host}" >> "$GITHUB_ENV" + echo "uamiId=${uamiId}" >> "$GITHUB_ENV" + + - name: Set outputs + id: resource_outputs + shell: bash + run: | + echo "uamiId=${{ env.uamiId }}" >> "$GITHUB_OUTPUT" + echo "serverHost=${{ env.serverHost }}" >> "$GITHUB_OUTPUT" diff --git a/.github/actions/it/action.yml b/.github/actions/it/action.yml new file mode 100644 index 000000000..c7774892f --- /dev/null +++ b/.github/actions/it/action.yml @@ -0,0 +1,676 @@ +name: 'IT Validation Workflows' +description: 'Execute validation workflows based on a validation plan' +inputs: + it_file: + description: 'Path to the validation plan file' + required: true + github_token: + description: 'GitHub token for API access' + required: true + default: ${{ github.token }} + +outputs: + results: + description: 'JSON string containing the results of all workflow executions' + value: ${{ steps.collect-results.outputs.results }} + report_timestamp: + description: 'Timestamp of the generated report' + value: ${{ steps.generate-report.outputs.timestamp }} + report_url: + description: 'URL to the generated report' + value: ${{ steps.output-urls.outputs.report_url }} + +runs: + using: 'composite' + steps: + - name: Read validation plan + id: set-matrix + shell: bash + run: | + PLAN_FILE="${{ inputs.it_file }}" + echo "Looking for plan file: $PLAN_FILE" + + if [ ! -f "$PLAN_FILE" ]; then + echo "Error: Plan file $PLAN_FILE not found" + echo "Current working directory: $(pwd)" + echo "GITHUB_WORKSPACE: $GITHUB_WORKSPACE" + echo "Listing current directory:" + ls -la + exit 1 + fi + + echo "Successfully found plan file: $PLAN_FILE" + + # Create matrix from plan + MATRIX=$(jq -c '.validation_scenarios | map({ + workflow: .workflow, + run_mode: (.run_mode // "parallel"), + scenarios: .scenarios + })' "$PLAN_FILE") + + echo "matrix=$MATRIX" >> $GITHUB_OUTPUT + + - name: Execute validation workflows + id: execute-workflows + uses: actions/github-script@v7 + env: + GITHUB_TOKEN: ${{ inputs.github_token }} + with: + script: | + const matrix = ${{ steps.set-matrix.outputs.matrix }}; + const allWorkflowRuns = []; + + for (const item of matrix) { + const workflow = item.workflow; + const runMode = item.run_mode; + const scenarios = item.scenarios; + const workflowRuns = []; + + console.log(`Starting to trigger workflow: ${workflow}`); + console.log(`Run mode: ${runMode}`); + console.log(`Number of scenarios to process: ${scenarios.length}`); + console.log(`Current owner: ${context.repo.owner}`); + console.log(`Current repo: ${context.repo.repo}`); + + if (runMode === 'serial') { + console.log('Running scenarios in serial mode'); + + for (const scenario of scenarios) { + try { + const scenarioName = scenario.scenario; + const scenarioInputs = scenario.inputs; + + console.log(`Triggering ${workflow} with scenario "${scenarioName}":`, JSON.stringify(scenarioInputs, null, 2)); + + // The github rest api for workflow dispatch requires all inputs to be strings. + // We need to convert any object values to JSON strings. + const inputs = Object.fromEntries( + Object.entries(scenarioInputs).map(([key, value]) => { + if (typeof value === 'object' && value !== null) { + return [key, JSON.stringify(value)]; + } + return [key, value]; + }) + ); + + // Trigger the workflow + const dispatchResponse = await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: workflow, + ref: context.ref, + inputs: inputs + }); + + console.log(`Workflow dispatch response:`, JSON.stringify(dispatchResponse.data, null, 2)); + + // Wait for 5 seconds for the workflow to be created + console.log('Waiting 5 seconds for workflow to be created...'); + await new Promise(resolve => setTimeout(resolve, 5000)); + + // Get the latest workflow run + let attempts = 0; + const maxAttempts = 5; + let run = null; + + while (attempts < maxAttempts) { + console.log(`Attempt ${attempts + 1} to find workflow run...`); + const runs = await github.rest.actions.listWorkflowRuns({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: workflow + }); + + if (runs.data.workflow_runs && runs.data.workflow_runs.length > 0) { + const potentialRun = runs.data.workflow_runs[0]; + // Get detailed run information + const runDetails = await github.rest.actions.getWorkflowRun({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: potentialRun.id + }); + + console.log(`Found workflow run:`, JSON.stringify({ + id: runDetails.data.id, + status: runDetails.data.status, + created_at: runDetails.data.created_at, + head_branch: runDetails.data.head_branch, + html_url: runDetails.data.html_url + }, null, 2)); + + run = runDetails.data; + break; + } + + console.log('No matching workflow run found, waiting 5 seconds...'); + await new Promise(resolve => setTimeout(resolve, 5000)); + attempts++; + } + + if (!run) { + console.log('Failed to find workflow run after all attempts'); + continue; + } + + // Wait for this workflow to complete before triggering the next one + console.log(`Waiting for workflow run ${run.id} to complete...`); + let status = run.status; + let waitAttempts = 0; + const maxWaitAttempts = 90; // 90 minutes maximum wait time + + while (status !== 'completed' && waitAttempts < maxWaitAttempts) { + // Wait for 60 seconds between checks + await new Promise(resolve => setTimeout(resolve, 60000)); + + // Get the workflow run status + const runData = await github.rest.actions.getWorkflowRun({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: run.id + }); + + status = runData.data.status; + console.log(`Workflow ${workflow} status: ${status} (wait attempt ${waitAttempts + 1}/${maxWaitAttempts})`); + + // If the workflow is still queued or in progress, continue waiting + if (status === 'queued' || status === 'in_progress') { + waitAttempts++; + continue; + } + + // If the workflow is completed, break the loop + if (status === 'completed') { + console.log(`Workflow ${workflow} completed with conclusion: ${runData.data.conclusion}`); + break; + } + + // If we get here, the status is something unexpected + console.log(`Unexpected status for workflow ${workflow}: ${status}`); + waitAttempts++; + } + + if (status !== 'completed') { + console.log(`Workflow ${workflow} did not complete within the maximum wait time. Moving to next scenario.`); + } + + workflowRuns.push({ + workflow: workflow, + scenario: scenarioInputs, + scenarioName: scenarioName, + runId: run.id, + runUrl: run.html_url, + startTime: run.created_at + }); + + console.log(`Successfully processed workflow run: ${run.id}`); + } catch (error) { + console.error(`Error processing scenario:`, error); + console.error(`Error details:`, JSON.stringify(error, null, 2)); + } + } + } else { + console.log('Running scenarios in parallel mode'); + + for (const scenario of scenarios) { + try { + const scenarioName = scenario.scenario; + const scenarioInputs = scenario.inputs; + + console.log(`Triggering ${workflow} with scenario "${scenarioName}":`, JSON.stringify(scenarioInputs, null, 2)); + + // The github rest api for workflow dispatch requires all inputs to be strings. + // We need to convert any object values to JSON strings. + const inputs = Object.fromEntries( + Object.entries(scenarioInputs).map(([key, value]) => { + if (typeof value === 'object' && value !== null) { + return [key, JSON.stringify(value)]; + } + return [key, value]; + }) + ); + + // Trigger the workflow + const dispatchResponse = await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: workflow, + ref: context.ref, + inputs: inputs + }); + + console.log(`Workflow dispatch response:`, JSON.stringify(dispatchResponse.data, null, 2)); + + // Wait for 5 seconds for the workflow to be created + console.log('Waiting 5 seconds for workflow to be created...'); + await new Promise(resolve => setTimeout(resolve, 5000)); + + // Get the latest workflow run + let attempts = 0; + const maxAttempts = 5; + let run = null; + + while (attempts < maxAttempts) { + console.log(`Attempt ${attempts + 1} to find workflow run...`); + const runs = await github.rest.actions.listWorkflowRuns({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: workflow + }); + + if (runs.data.workflow_runs && runs.data.workflow_runs.length > 0) { + const potentialRun = runs.data.workflow_runs[0]; + // Get detailed run information + const runDetails = await github.rest.actions.getWorkflowRun({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: potentialRun.id + }); + + console.log(`Found workflow run:`, JSON.stringify({ + id: runDetails.data.id, + status: runDetails.data.status, + created_at: runDetails.data.created_at, + head_branch: runDetails.data.head_branch, + html_url: runDetails.data.html_url + }, null, 2)); + + run = runDetails.data; + break; + } + + console.log('No matching workflow run found, waiting 5 seconds...'); + await new Promise(resolve => setTimeout(resolve, 5000)); + attempts++; + } + + if (!run) { + console.log('Failed to find workflow run after all attempts'); + continue; + } + + workflowRuns.push({ + workflow: workflow, + scenario: scenarioInputs, + scenarioName: scenarioName, + runId: run.id, + runUrl: run.html_url, + startTime: run.created_at + }); + + console.log(`Successfully tracked workflow run: ${run.id}`); + } catch (error) { + console.error(`Error processing scenario:`, error); + console.error(`Error details:`, JSON.stringify(error, null, 2)); + } + } + } + + allWorkflowRuns.push(...workflowRuns); + } + + console.log(`Total workflow runs tracked: ${allWorkflowRuns.length}`); + console.log('Workflow runs:', JSON.stringify(allWorkflowRuns, null, 2)); + + core.setOutput('workflow_runs', JSON.stringify(allWorkflowRuns)); + + - name: Wait for workflows and collect results + id: collect-results + uses: actions/github-script@v7 + env: + GITHUB_TOKEN: ${{ inputs.github_token }} + with: + script: | + const workflowRuns = JSON.parse('${{ steps.execute-workflows.outputs.workflow_runs }}'); + const results = []; + + for (const run of workflowRuns) { + console.log(`Processing workflow ${run.workflow} run ${run.runId}...`); + + // Get the current workflow run status + const runData = await github.rest.actions.getWorkflowRun({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: run.runId + }); + + let status = runData.data.status; + + // If the workflow is already completed (likely from serial execution), use it directly + if (status === 'completed') { + console.log(`Workflow ${run.workflow} is already completed with conclusion: ${runData.data.conclusion}`); + results.push({ + workflow: run.workflow, + scenario: run.scenario, + scenarioName: run.scenarioName, + status: runData.data.conclusion, + runId: run.runId, + runUrl: run.runUrl, + startTime: run.startTime, + endTime: runData.data.updated_at + }); + continue; + } + + // For workflows that are still running (parallel mode), wait for completion + console.log(`Waiting for workflow ${run.workflow} run ${run.runId}...`); + + let attempts = 0; + const maxAttempts = 60; // 60 minutes maximum wait time + + while (status !== 'completed' && attempts < maxAttempts) { + try { + // Wait for 60 seconds between checks + await new Promise(resolve => setTimeout(resolve, 60000)); + + // Get the workflow run status + const runData = await github.rest.actions.getWorkflowRun({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: run.runId + }); + + status = runData.data.status; + console.log(`Workflow ${run.workflow} status: ${status} (attempt ${attempts + 1}/${maxAttempts})`); + + // If the workflow is still queued or in progress, continue waiting + if (status === 'queued' || status === 'in_progress') { + attempts++; + continue; + } + + // If the workflow is completed, break the loop + if (status === 'completed') { + break; + } + + // If we get here, the status is something unexpected + console.log(`Unexpected status for workflow ${run.workflow}: ${status}`); + attempts++; + } catch (error) { + console.log(`Error checking workflow status: ${error.message}`); + attempts++; + } + } + + if (status !== 'completed') { + console.log(`Workflow ${run.workflow} did not complete within the maximum wait time`); + results.push({ + workflow: run.workflow, + scenario: run.scenario, + scenarioName: run.scenarioName, + status: 'timeout', + runId: run.runId, + runUrl: run.runUrl, + startTime: run.startTime, + endTime: new Date().toISOString() + }); + continue; + } + + // Get the final workflow run data + const finalRunData = await github.rest.actions.getWorkflowRun({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: run.runId + }); + + results.push({ + workflow: run.workflow, + scenario: run.scenario, + scenarioName: run.scenarioName, + status: finalRunData.data.conclusion, + runId: run.runId, + runUrl: run.runUrl, + startTime: run.startTime, + endTime: finalRunData.data.updated_at + }); + } + + core.setOutput('results', JSON.stringify(results)); + + - name: Generate Markdown report + id: generate-report + shell: bash + run: | + TIMESTAMP=$(date +"%Y-%m-%d-%H-%M-%S") + echo "timestamp=$TIMESTAMP" >> $GITHUB_OUTPUT + echo "Current directory: $(pwd)" + + # Generate table rows and summary + RESULTS='${{ steps.collect-results.outputs.results }}' + rows="" + total=0 + success=0 + failure=0 + timeout=0 + cancelled=0 + other_failed=0 + for row in $(echo "$RESULTS" | jq -r '.[] | @base64'); do + _jq() { + echo ${row} | base64 --decode | jq -r "$1" + } + workflow=$(_jq '.workflow') + scenario_name=$(_jq '.scenarioName // empty') + scenario=$(_jq '.scenario | if type=="object" then to_entries | map("\(.key): \(.value)") | join(", ") else tostring end') + status=$(_jq '.status') + runUrl=$(_jq '.runUrl') + startTime=$(_jq '.startTime') + endTime=$(_jq '.endTime') + + # Use scenario name if available, otherwise use the scenario details + display_scenario="${scenario_name:-${scenario}}" + + # Calculate duration + start=$(date -d "$startTime" +%s) + end=$(date -d "$endTime" +%s) + duration=$((end - start)) + duration_str=$(printf '%dh:%dm:%ds' $((duration/3600)) $((duration%3600/60)) $((duration%60))) + + # Count status + total=$((total+1)) + if [ "$status" = "success" ]; then + success=$((success+1)) + elif [ "$status" = "failure" ]; then + failure=$((failure+1)) + elif [ "$status" = "timeout" ]; then + timeout=$((timeout+1)) + elif [ "$status" = "cancelled" ]; then + cancelled=$((cancelled+1)) + else + # Any other non-success status + other_failed=$((other_failed+1)) + fi + + # Create table row + rows+="| ${workflow} | \`${display_scenario}\` | ${status} | ${duration_str} | [View Run](${runUrl}) |\n" + done + + # Create a temporary file with the content + { + echo "# Validation Workflow Results" + echo "" + echo "## Summary" + echo "- Total Workflows: ${total}" + echo "- Successful: ${success}" + echo "- Failed: ${failure}" + echo "- Timed Out: ${timeout}" + echo "- Cancelled: ${cancelled}" + echo "- Other Failed: ${other_failed}" + echo "" + echo "## Detailed Results" + echo "" + echo "| Workflow | Scenario | Status | Duration | Run URL |" + echo "|----------|----------|---------|-----------|----------|" + echo -e "${rows}" + echo "" + echo "## Execution Notes" + echo "- Workflows marked with \`run_mode: serial\` are executed one after another" + echo "- Other workflows are executed in parallel" + } > "${TIMESTAMP}-report.md" + + - name: Upload report + uses: actions/upload-artifact@v4.6.2 + with: + name: validation-report-${{ steps.generate-report.outputs.timestamp }} + path: ${{ steps.generate-report.outputs.timestamp }}-report.md + + - name: Setup Git + shell: bash + run: | + git config --global user.name "GitHub Actions" + git config --global user.email "actions@github.com" + + - name: Create/Update IT Branch + shell: bash + run: | + # Debug information + echo "Current directory: $(pwd)" + echo "Listing files in current directory:" + ls -la + echo "Listing files in workspace:" + ls -la $GITHUB_WORKSPACE + + # Find the report file + REPORT_FILE=$(find $GITHUB_WORKSPACE -name "${{ steps.generate-report.outputs.timestamp }}-report.md") + echo "Found report file at: $REPORT_FILE" + + if [ ! -f "$REPORT_FILE" ]; then + echo "Error: Report file not found!" + exit 1 + fi + + # Fetch all branches + git fetch origin + + # Check if it branch exists remotely + if git ls-remote --exit-code --heads origin it; then + echo "it branch exists. Checking out..." + git checkout it + git pull origin it + else + echo "it branch does not exist. Creating new it branch from current HEAD..." + git checkout -b it + fi + + # Use existing it-report directory if present, otherwise create it + if [ -d "it-report" ]; then + echo "it-report directory exists. Using existing directory." + else + echo "it-report directory does not exist. Creating it." + mkdir it-report + fi + + # Copy the report to it-report directory + cp "$REPORT_FILE" it-report/ + + # Add and commit the report + git add it-report/${{ steps.generate-report.outputs.timestamp }}-report.md + git commit -m "Add validation report ${{ steps.generate-report.outputs.timestamp }}" || echo "Nothing to commit." + + # Push to the it branch + git push origin it + + - name: Output Report URL + id: output-urls + shell: bash + run: | + REPORT_URL="https://github.com/${{ github.repository }}/blob/it/it-report/${{ steps.generate-report.outputs.timestamp }}-report.md" + RAW_REPORT_URL="https://raw.githubusercontent.com/${{ github.repository }}/it/it-report/${{ steps.generate-report.outputs.timestamp }}-report.md" + + echo "::notice::📊 Validation Report URL: $REPORT_URL" + echo "::notice::📊 Raw Report URL: $RAW_REPORT_URL" + echo "report_url=$REPORT_URL" >> $GITHUB_OUTPUT + + - name: Check workflow results and fail if any failed + shell: bash + run: | + RESULTS='${{ steps.collect-results.outputs.results }}' + + # Parse results and check for failures + failed_workflows=() + timeout_workflows=() + cancelled_workflows=() + other_failed_workflows=() + total=0 + success=0 + failure=0 + timeout=0 + cancelled=0 + other_failed=0 + + for row in $(echo "$RESULTS" | jq -r '.[] | @base64'); do + _jq() { + echo ${row} | base64 --decode | jq -r "$1" + } + workflow=$(_jq '.workflow') + scenario_name=$(_jq '.scenarioName // empty') + scenario=$(_jq '.scenario | if type=="object" then to_entries | map("\(.key): \(.value)") | join(", ") else tostring end') + status=$(_jq '.status') + runUrl=$(_jq '.runUrl') + + # Use scenario name if available, otherwise use the scenario details + display_scenario="${scenario_name:-${scenario}}" + + # Count status and track failed workflows + total=$((total+1)) + if [ "$status" = "success" ]; then + success=$((success+1)) + elif [ "$status" = "failure" ]; then + failure=$((failure+1)) + failed_workflows+=("${workflow} (${display_scenario}): ${runUrl}") + elif [ "$status" = "timeout" ]; then + timeout=$((timeout+1)) + timeout_workflows+=("${workflow} (${display_scenario}): ${runUrl}") + elif [ "$status" = "cancelled" ]; then + cancelled=$((cancelled+1)) + cancelled_workflows+=("${workflow} (${display_scenario}): ${runUrl}") + else + # Any other non-success status should be treated as a failure + other_failed=$((other_failed+1)) + other_failed_workflows+=("${workflow} (${display_scenario}) [${status}]: ${runUrl}") + fi + done + + # Display summary + echo "::notice::📊 Workflow Execution Summary:" + echo "::notice:: Total: ${total}, Success: ${success}, Failed: ${failure}, Timeout: ${timeout}, Cancelled: ${cancelled}, Other Failed: ${other_failed}" + + # If there are failed workflows, display them and fail the IT + if [ ${#failed_workflows[@]} -gt 0 ]; then + echo "::error::❌ The following workflows failed:" + for failed in "${failed_workflows[@]}"; do + echo "::error:: - ${failed}" + done + fi + + # If there are timeout workflows, display them and fail the IT + if [ ${#timeout_workflows[@]} -gt 0 ]; then + echo "::error::⏰ The following workflows timed out:" + for timeout in "${timeout_workflows[@]}"; do + echo "::error:: - ${timeout}" + done + fi + + # If there are cancelled workflows, display them and fail the IT + if [ ${#cancelled_workflows[@]} -gt 0 ]; then + echo "::error::🚫 The following workflows were cancelled:" + for cancelled in "${cancelled_workflows[@]}"; do + echo "::error:: - ${cancelled}" + done + fi + + # If there are other failed workflows, display them and fail the IT + if [ ${#other_failed_workflows[@]} -gt 0 ]; then + echo "::error::❌ The following workflows failed with other statuses:" + for other_failed in "${other_failed_workflows[@]}"; do + echo "::error:: - ${other_failed}" + done + fi + + # Fail the IT workflow if any workflow failed, timed out, was cancelled, or had other failure statuses + if [ ${#failed_workflows[@]} -gt 0 ] || [ ${#timeout_workflows[@]} -gt 0 ] || [ ${#cancelled_workflows[@]} -gt 0 ] || [ ${#other_failed_workflows[@]} -gt 0 ]; then + echo "::error::❌ IT workflow failed because ${#failed_workflows[@]} workflow(s) failed, ${#timeout_workflows[@]} workflow(s) timed out, ${#cancelled_workflows[@]} workflow(s) were cancelled, and ${#other_failed_workflows[@]} workflow(s) had other failure statuses." + exit 1 + fi + + echo "::notice::✅ All workflows completed successfully!" \ No newline at end of file diff --git a/.github/actions/setupmaven/action.yml b/.github/actions/setupmaven/action.yml new file mode 100644 index 000000000..50f50652e --- /dev/null +++ b/.github/actions/setupmaven/action.yml @@ -0,0 +1,26 @@ +name: Set Up Maven +description: Set up Maven with github token. +inputs: + token: + description: "GitHub token" + required: true +runs: + using: "composite" + steps: + - uses: actions/checkout@v4 + - name: Set up Apache Maven and JDK + uses: actions/setup-java@v4 + with: + distribution: 'microsoft' + java-version: 21 + server-id: github # Value of the distributionManagement/repository/id field of the pom.xml + server-username: MAVEN_USERNAME # env variable for username + server-password: MAVEN_TOKEN # env variable for token + - name: Set Maven env + env: + MAVEN_USERNAME: github + MAVEN_TOKEN: ${{ inputs.token }} + shell: bash + run: | + echo "MAVEN_USERNAME=${MAVEN_USERNAME}" >> $GITHUB_ENV + echo "MAVEN_TOKEN=${MAVEN_TOKEN}" >> $GITHUB_ENV \ No newline at end of file diff --git a/.github/actions/setvars/action.yml b/.github/actions/setvars/action.yml new file mode 100644 index 000000000..a9991b1ec --- /dev/null +++ b/.github/actions/setvars/action.yml @@ -0,0 +1,13 @@ +name: "Set environment variables" +description: "Configures environment variables for a workflow" +inputs: + varFilePath: + description: "File path to variable file or directory. Defaults to ./.github/variables/* if none specified and runs against each file in that directory." + required: false + default: ./.github/variables/* +runs: + using: "composite" + steps: + - run: | + sed "" ${{ inputs.varFilePath }} >> $GITHUB_ENV + shell: bash diff --git a/.github/docs/check-arm-vm-size.md b/.github/docs/check-arm-vm-size.md new file mode 100644 index 000000000..dd318afb5 --- /dev/null +++ b/.github/docs/check-arm-vm-size.md @@ -0,0 +1,73 @@ +## GitHub Action: Check ARM VM Size Changes + +### Overview +This GitHub Action runs on a schedule to check for changes in Azure ARM VM sizes and creates a pull request to update configurations if changes are detected. + +The action will compare the latest ARM VM sizes queried using AZ CLI with those listed in the variable azure.armBased.vmSize.list within oracle/weblogic-azure/resources/azure-common.properties. If changes are detected, it will initiate a pull request to the main branch of the current repository that runs the action. + +### Schedule +- **Frequency:** Every 14 days (2 weeks) +- **Schedule Expression:** `0 0 */14 * *` (Runs at midnight (00:00) UTC) + +The schedule event only happens in [azure-javaee/weblogic-azure](https://github.com/azure-javaee/weblogic-azure). + +If you want to run the action in your repository, you have to trigger it from Web Browser. + +### Environment Variables +- **azureCredentials:** Secret for Azure credentials +- **repoName:** Repository name set to "weblogic-azure" +- **userEmail:** Secret for user Email of GitHub acount to access GitHub repository +- **userName:** Secret for user name of GitHub account + +### Jobs +#### check-vm-sizes +- **Runs on:** `ubuntu-latest` +- **Steps:** + 1. **Checkout repository:** Checks out the repository using `actions/checkout@v2`. + + 2. **Azure Login:** Logs into Azure using `azure/login@v1`. + + 3. **Check for VM size changes:** + - Reads from `resources/azure-common.properties`. + - Extracts and compares current VM sizes with the latest available. + - Determines if there are changes and prepares data for output. + + 4. **Create PR if changes detected:** + - Conditionally creates a pull request if changes in ARM VM sizes are detected. + - Updates the ARM VM sizes configuration in `resources/azure-common.properties`. + - Commits changes to a new branch and pushes to origin. + - Creates a pull request with a title and description based on detected changes. + +### Run the action + +You can use `.github/resource/azure-credential-setup-wls-vm.sh` to create GitHub Action Secret for the pipeline. + +1. Fill in `.github/resource/credentials-params-wls-vm.yaml` with your values. + + | Variable Name | Value | + |----------------|----------------------| + | OTN_USERID | Oracle single sign-on userid. If you don't have one, sign up from [Create Your Oracle Account](https://profile.oracle.com/myprofile/account/create-account.jspx?nexturl=https%3A%2F%2Fsupport.oracle.com&pid=mos) | + | OTN_PASSWORD | Password for Oracle single sign-on userid. | + | WLS_PSW | Password for WebLogic Server. | + | USER_EMAIL | User Email of GitHub acount to access GitHub repository. | + | USER_NAME | User name of GitHub account. | + | GIT_TOKEN | GitHub token to access GitHub repository.
Make sure the token have permissions:
- Read and write of Pull requests.
- Read and write of Contents. | + +2. Set up secret + + Run `azure-credential-setup-wls-vm.sh` to set up secret. + + ```shell + bash .github/resource/azure-credential-setup-wls-vm.sh + ``` + + Follow the output to set up secrets. + +3. Trigger the workflow + + - Fork this repo from [oracle/weblogic-azure](https://github.com/azure-javaee/weblogic-azure). + + - Enable workflow in the fork. Select **Actions**, then follow the instructions to enable workflow. + + - Select **Actions** -> **Check ARM VM Size Changes** -> **Run workflow** to run the workflow. + diff --git a/.github/it/README.md b/.github/it/README.md new file mode 100644 index 000000000..268a55c15 --- /dev/null +++ b/.github/it/README.md @@ -0,0 +1,286 @@ +# IT Validation Configuration + +## Overview + +The IT validation system is a comprehensive integration testing framework designed to validate Oracle WebLogic Server deployments on Azure across multiple scenarios and configurations. It automates the execution of various deployment scenarios, monitors their progress, and generates detailed reports to ensure the reliability and quality of the Azure WebLogic templates. + +### Key Features + +- **Multi-Scenario Testing**: Execute multiple test scenarios simultaneously or sequentially +- **Flexible Execution Modes**: Support for both parallel and serial execution modes +- **Comprehensive Reporting**: Detailed reports with success/failure statistics and execution URLs +- **Automated Monitoring**: Real-time tracking of workflow execution with timeout protection +- **Resource Management**: Efficient cleanup and resource optimization for cost-effective testing + +### Use Cases + +- **Regression Testing**: Validate WebLogic templates after code changes or updates +- **Release Validation**: Comprehensive testing before production releases +- **Configuration Testing**: Verify different deployment configurations and parameters +- **Performance Monitoring**: Track deployment times and resource utilization + +## Table of Contents + +- [System Architecture](#system-architecture) +- [Configuration Structure](#configuration-structure) + - [Scenarios Structure](#scenarios-structure) + - [Execution Modes](#execution-modes) +- [How It Works](#how-it-works) +- [Available Files](#available-files) + - [File Content Overview](#file-content-overview) +- [Getting Started](#getting-started) + - [Quick Start Guide](#quick-start-guide) + - [Prerequisites](#prerequisites) +- [IT Action Usage](#it-action-usage) + - [Action Inputs](#action-inputs) + - [Action Outputs](#action-outputs) +- [Structure Requirements](#structure-requirements) +- [Serial vs Parallel Execution](#serial-vs-parallel-execution) +- [Report Generation](#report-generation) + - [Status Tracking](#status-tracking) + - [Accessing Reports](#accessing-reports) +- [Error Handling](#error-handling) +- [Trouble Shooting](#trouble-shooting) + + +## System Architecture + +The IT validation system consists of: + +1. **Validation Plan Files** (this directory): JSON files defining what to test +2. **IT Action** (`/.github/actions/it/action.yml`): Reusable composite action that executes the plans +3. **IT Workflows** (`/.github/workflows/it-validation-*.yaml`): Workflows that trigger the action with specific plans +3. **Target Workflows** (`/.github/workflows/testWls*.yml` and `buildWls*.yml`): The actual validation workflows that get executed + +## Configuration Structure + +The validation plan files use the following structure: + +### Scenarios Structure +Each validation plan defines scenarios with descriptive names: + +```json +{ + "validation_scenarios": [ + { + "workflow": "testWlsVmAdmin.yml", + "run_mode": "serial", + "scenarios": [ + { + "scenario": "Test Admin Server on VM with mssqlserver", + "inputs": { + "location": "centralus" + } + } + ] + } + ] +} +``` + +### Execution Modes + +You can control how scenarios within a workflow are executed by using the optional `run_mode` property: + +- **`"run_mode": "serial"`**: Scenarios are executed one after another. Each scenario must complete before the next one starts. +- **`"run_mode": "parallel"`** or **no `run_mode` specified**: Scenarios are executed simultaneously (default behavior). + +**Example with serial execution:** +```json +{ + "validation_scenarios": [ + { + "workflow": "testWlsVmCluster.yml", + "run_mode": "serial", + "scenarios": [ + { + "scenario": "First scenario", + "inputs": { /* ... */ } + }, + { + "scenario": "Second scenario", + "inputs": { /* ... */ } + } + ] + } + ] +} +``` + +**When to use serial mode:** +- Resource-intensive scenarios that might conflict if run simultaneously +- Scenarios that need to run in a specific order +- Limited resource environments where parallel execution might cause failures + +## How It Works + +1. **IT Workflows**: The `it-validation-*.yaml` workflows are triggered (manually or scheduled) + +2. **Plan File Mapping**: Each IT workflow maps its input to a specific validation plan file in this directory + +3. **Action Execution**: The workflow calls the IT action (`/.github/actions/it/action.yml`) with the plan file path + +4. **Plan Processing**: The action reads the validation plan and processes each scenario + +5. **Execution Mode**: The optional `run_mode` property controls whether scenarios are executed serially or in parallel + +6. **Workflow Triggering**: The action triggers the specified target workflows with the scenario inputs + +7. **Monitoring**: The action monitors workflow execution and waits for completion + +8. **Reporting**: Results are compiled into comprehensive reports and stored in the `it` branch + +## Available Files + +- `validation-plan-aks.json`: Azure Kubernetes Service (AKS) validation scenarios for WebLogic Server deployments +- `validation-plan-build.json`: Build-only validation scenarios for template compilation and syntax checking +- `validation-plan-vm-admin.json`: WebLogic Admin Server on VM validation scenarios +- `validation-plan-vm-cluster.json`: WebLogic Configured Cluster on VM validation scenarios +- `validation-plan-vm-dynamic-cluster.json`: WebLogic Dynamic Cluster on VM validation scenarios + +### File Content Overview + +Each validation plan targets specific WebLogic deployment scenarios: + +- **AKS Plans**: Test WebLogic Server deployments on Azure Kubernetes Service with various database configurations +- **VM Plans**: Test WebLogic Server deployments on Azure Virtual Machines in different topologies (Admin Server, Configured Cluster, Dynamic Cluster) +- **Build Plans**: Validate artifact compilation and template syntax without actual deployments + +## Getting Started + +### Quick Start Guide + +1. **Choose a Validation Plan**: Select the appropriate validation plan file based on your testing needs: + - For AKS deployments: `validation-plan-aks.json` + - For Admin Server on VM: `validation-plan-vm-admin.json` + - For Configured Cluster on VM: `validation-plan-vm-cluster.json` + - For Dynamic Cluster on VM: `validation-plan-vm-dynamic-cluster.json` + - For build validation only: `validation-plan-build.json` + +2. **Trigger IT Validation**: Use the GitHub Actions interface to manually trigger a IT validation workflow: + - Go to the "Actions" tab in the repository + - Select the appropriate `it-validation-*` workflow: + - `IT Validation for AKS` - for AKS deployments + - `IT Validation for VM Admin` - for Admin Server on VM + - `IT Validation for VM Cluster` - for Configured Cluster on VM + - `IT Validation for VM Dynamic Cluster` - for Dynamic Cluster on VM + - `IT Validation for Build` - for build-only validation + - Click "Run workflow" and select your desired validation plan + +3. **Monitor Progress**: Track the execution progress in the Actions tab and view real-time logs + +4. **Review Results**: Check the generated reports in the `it` branch under `it-report/` directory + +### Prerequisites + +Before using the IT validation system, ensure: + +- [ ] Azure subscription with appropriate permissions +- [ ] GitHub repository with Actions enabled +- [ ] Required secrets configured in repository settings. The repository secrets set by the [setup-credentials.sh](../workflows/setup-credentials.sh) script must be set with current and valid values before any of these workflows will run. +- [ ] Access to the `it` branch for report storage + +## IT Action Usage + +The validation plans are consumed by the IT action located at `/.github/actions/it/action.yml`. + +### Action Inputs + +| Input | Description | Required | +|-------|-------------|----------| +| `it_file` | Path to the validation plan file | Yes | + +### Action Outputs + +| Output | Description | +|--------|-------------| +| `results` | JSON string containing the results of all workflow executions | +| `report_timestamp` | Timestamp of the generated report | +| `report_url` | URL to the generated report on the IT branch | + +## Structure Requirements + +- Each plan must have a `validation_scenarios` array +- Each item in the array must have a `workflow` and `scenarios` field +- Each scenario must have a `scenario` name and an `inputs` object +- The optional `run_mode` field can be set to `"serial"` or `"parallel"` (default) +- Only the `inputs` object content is passed to the target workflow + +## Serial vs Parallel Execution + +### Parallel Execution (Default) +- All scenarios within a workflow are triggered simultaneously +- Faster overall execution time +- Suitable for independent scenarios that don't compete for resources + +### Serial Execution +- Scenarios are executed one after another +- Each scenario must complete before the next one starts +- Longer overall execution time but better resource management +- Includes waiting and monitoring between scenarios +- Recommended for resource-intensive workloads or debugging + +## Report Generation + +The IT action generates comprehensive reports that include: + +- **Summary Statistics**: Total workflows, success/failure counts including cancelled and timeout scenarios +- **Detailed Results**: Individual workflow results with duration and status +- **Execution URLs**: Direct links to workflow runs +- **Execution Notes**: Information about serial vs parallel execution + +Reports are: +1. Uploaded as GitHub Actions artifacts +2. Committed to the `it` branch in the `it-report/` directory +3. Accessible via the repository's IT branch + +### Status Tracking + +The system tracks all execution outcomes: +- **Success**: Workflows completed successfully +- **Failure**: Workflows failed during execution +- **Timeout**: Workflows exceeded the 60-minute timeout limit +- **Cancelled**: Workflows manually cancelled by users +- **Other Failed**: Workflows with any other non-success status + +### Accessing Reports + +Reports can be accessed in multiple ways: + +1. **GitHub Actions Artifacts**: Download reports directly from the workflow run artifacts +2. **IT Branch**: Browse reports in the `it` branch under `it-report/` directory +3. **Direct Links**: Use the `report_url` output from the IT action +4. **API Access**: Programmatically access reports via GitHub API + +#### Report File Naming Convention + +Reports follow the naming pattern: `report-YYYYMMDD-HHMMSS.json` + +Example: `report-20250804-103000.json` (August 4, 2025 at 10:30:00 UTC) + +## Error Handling + +The IT action includes robust error handling: +- **Timeout Protection**: 60-minute maximum wait time per workflow +- **Failure Detection**: IT workflow fails if any triggered workflow fails, times out, or is cancelled + +## Trouble Shooting + +### Debugging with tmate + +One of the biggest pain points to develop GitHub actions for our Java EE solution offerings is that it's hard to debug them by direct interacting with the host system on which the actual Actions are running. + +I found a GitHub action `tmate` which unlocks the door for debugging GitHub actions using SSH or Web shell, pls refer to [Debugging with tmate](https://github.com/marketplace/actions/debugging-with-tmate) or to the [tmate docs](https://mxschmitt.github.io/action-tmate/) for detailed how-to instructions. + +And here is an example where `tmate` was applied in `integration-test` workflow of `liberty-on-aks` repo: +* https://github.com/WASdev/azure.liberty.aks/pull/62/files#diff-b6766eb8febc0c51651250cd0cdfb44c4f0d3256470d88e62bf82fd46aa73ae0R119-R121 + + +## Authentication of the tmate session. +> Refer to this [issue](https://github.com/mxschmitt/action-tmate/issues/163)’s [comment](https://github.com/mxschmitt/action-tmate/issues/163#issuecomment-1651436411), + +this [action](https://github.com/mxschmitt/action-tmate) uses the ssh public key from the github account as `authorised_keys`. +So if you have multiple private keys in your local machine, you may need to specify the private key used for `*.tmate.io` in your `~/.ssh/config` file. + +![tmate-sshkey.png](tmate-sshkey.png) + diff --git a/.github/it/tmate-sshkey.png b/.github/it/tmate-sshkey.png new file mode 100644 index 000000000..7e4e383f6 Binary files /dev/null and b/.github/it/tmate-sshkey.png differ diff --git a/.github/it/validation-plan-aks.json b/.github/it/validation-plan-aks.json new file mode 100644 index 000000000..d59d08a1a --- /dev/null +++ b/.github/it/validation-plan-aks.json @@ -0,0 +1,36 @@ +{ + "validation_scenarios": [ + { + "workflow": "testWlsAksWithDependencyCreation.yml", + "run_mode": "serial", + "scenarios": [ + { + "scenario": "Deploy with passwordless postgresql", + "inputs": { + "location": "centralus", + "databaseType": "postgresql-passwordless(flexible)" + } + }, + { + "scenario": "Disable the App Gateway Ingress Controller", + "inputs": { + "location": "centralus", + "configurations_for_it": { + "enableAppGWIngress": "false" + } + } + }, + { + "scenario": "Bring you own AKS clusters and using postgresql", + "inputs": { + "location": "centralus", + "configurations_for_it": { + "createAKSCluster": "false", + "aksClusterName": "my-existing-aks-cluster" + } + } + } + ] + } + ] +} \ No newline at end of file diff --git a/.github/it/validation-plan-build.json b/.github/it/validation-plan-build.json new file mode 100644 index 000000000..50ff53c38 --- /dev/null +++ b/.github/it/validation-plan-build.json @@ -0,0 +1,55 @@ +{ + "validation_scenarios": [ + { + "workflow": "buildWlsAksArtifact.yml", + "scenarios": [ + { + "scenario": "Build WLS on AKS artifact", + "inputs": { + } + + } + ] + }, + { + "workflow": "buildWlsVm4AsArtifact.yml", + "scenarios": [ + { + "scenario": "Build Admin Server VM artifact", + "inputs": { + } + } + ] + }, + { + "workflow": "buildWlsVm4CcArtifact.yml", + "scenarios": [ + { + "scenario": "Build Configured Cluster VM artifact", + "inputs": { + } + } + ] + }, + { + "workflow": "buildWlsVm4DcArtifact.yml", + "scenarios": [ + { + "scenario": "Build Dynamic Cluster VM artifact", + "inputs": { + } + } + ] + }, + { + "workflow": "buildWlsVm4SnArtifact.yml", + "scenarios": [ + { + "scenario": "Build Single Node VM artifact", + "inputs": { + } + } + ] + } + ] +} \ No newline at end of file diff --git a/.github/it/validation-plan-vm-admin.json b/.github/it/validation-plan-vm-admin.json new file mode 100644 index 000000000..26090ed7a --- /dev/null +++ b/.github/it/validation-plan-vm-admin.json @@ -0,0 +1,33 @@ +{ + "validation_scenarios": [ + { + "workflow": "testWlsVmAdmin.yml", + "scenarios": [ + { + "scenario": "Test Admin Server on VM with mssqlserver", + "inputs": { + "location": "centralus" + } + }, + { + "scenario": "Test Admin Server on VM with passwordless postgresql", + "inputs": { + "location": "centralus", + "databaseType": "postgresql-passwordless(flexible)" + } + }, + { + "scenario": "Bring your own VNET for Admin Server on VM", + "inputs": { + "location": "centralus", + "configurations_for_it": { + "virtualNetworkNewOrExisting": "existing", + "virtualNetworkName": "myvirtualNetworkName-vm-admin", + "subnetName": "mySubnet-vm-admin" + } + } + } + ] + } + ] +} \ No newline at end of file diff --git a/.github/it/validation-plan-vm-cluster.json b/.github/it/validation-plan-vm-cluster.json new file mode 100644 index 000000000..fbe0f006a --- /dev/null +++ b/.github/it/validation-plan-vm-cluster.json @@ -0,0 +1,37 @@ +{ + "validation_scenarios": [ + { + "workflow": "testWlsVmCluster.yml", + "run_mode": "serial", + "scenarios": [ + { + "scenario": "Test Configured Cluster on VM with mssqlserver", + "inputs": { + "location": "centralus", + "databaseType": "mssqlserver" + } + }, + { + "scenario": "Bring your own VNET for Cluster on VM", + "inputs": { + "location": "centralus", + "databaseType": "mssqlserver", + "configurations_for_it": { + "virtualNetworkNewOrExisting": "existing", + "virtualNetworkName": "my-existing-cluster-vnet", + "subnetForCluster": "my-existing-cluster-subnet-for-cluster", + "subnetForAppGateway": "my-existing-cluster-subnet-for-app-gateway" + } + } + }, + { + "scenario": "Test Configured Cluster on VM with PostgreSQL passwordless", + "inputs": { + "location": "centralus", + "databaseType": "postgresql-passwordless(flexible)" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/.github/it/validation-plan-vm-dynamic-cluster.json b/.github/it/validation-plan-vm-dynamic-cluster.json new file mode 100644 index 000000000..f7266db3a --- /dev/null +++ b/.github/it/validation-plan-vm-dynamic-cluster.json @@ -0,0 +1,24 @@ +{ + "validation_scenarios": [ + { + "workflow": "testWlsVmDynamicCluster.yml", + "run_mode": "serial", + "scenarios": [ + { + "scenario": "Test Dynamic Cluster on VM with mssqlserver", + "inputs": { + "location": "centralus", + "databaseType": "mssqlserver" + } + }, + { + "scenario": "Test Dynamic Cluster on VM with PostgreSQL passwordless", + "inputs": { + "location": "centralus", + "databaseType": "postgresql-passwordless(flexible)" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/.github/resource/azure-credential-setup-wls-aks.sh b/.github/resource/azure-credential-setup-wls-aks.sh new file mode 100644 index 000000000..31b8af155 --- /dev/null +++ b/.github/resource/azure-credential-setup-wls-aks.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -Eeuo pipefail + +echo "Execute azure-credential-setup.sh - Start------------------------------------------" + +## Create Azure Credentials +SERVICE_PRINCIPAL_NAME_WLS_AKS="sp-${REPO_NAME}-wls-aks-$(date +%s)" +echo "Creating Azure Service Principal with name: $SERVICE_PRINCIPAL_NAME_WLS_AKS" +SUBSCRIPTION_ID=$(az account show --query id -o tsv| tr -d '\r\n') + +AZURE_CREDENTIALS=$(az ad sp create-for-rbac --name ${SERVICE_PRINCIPAL_NAME_WLS_AKS} --role="Contributor" --scopes="/subscriptions/${SUBSCRIPTION_ID}" --sdk-auth --only-show-errors) +SP_ID=$( az ad sp list --display-name $SERVICE_PRINCIPAL_NAME_WLS_AKS --query \[0\].id -o tsv | tr -d '\r\n') +az role assignment create --assignee ${SP_ID} --scope="/subscriptions/${SUBSCRIPTION_ID}" --role "User Access Administrator" + +## Set the Azure Credentials as a secret in the repository +gh secret --repo $(gh repo set-default --view) set "AZURE_CREDENTIALS" -b"${AZURE_CREDENTIALS}" +gh variable --repo $(gh repo set-default --view) set "SERVICE_PRINCIPAL_NAME_WLS_AKS" -b"${SERVICE_PRINCIPAL_NAME_WLS_AKS}" + +echo "Execute azure-credential-setup.sh - End--------------------------------------------" diff --git a/.github/resource/azure-credential-setup-wls-vm.sh b/.github/resource/azure-credential-setup-wls-vm.sh new file mode 100644 index 000000000..9d57cffb9 --- /dev/null +++ b/.github/resource/azure-credential-setup-wls-vm.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set -Eeuo pipefail + +echo "Execute azure-credential-setup.sh - Start------------------------------------------" + +## Create Azure Credentials +SERVICE_PRINCIPAL_NAME_WLS_VM="sp-${REPO_NAME}-$(date +%s)" +echo "Creating Azure Service Principal with name: $SERVICE_PRINCIPAL_NAME_WLS_VM" +SUBSCRIPTION_ID=$(az account show --query id -o tsv| tr -d '\r\n') + +SERVICE_PRINCIPAL=$(az ad sp create-for-rbac --name ${SERVICE_PRINCIPAL_NAME_WLS_VM} --role="Contributor" --scopes="/subscriptions/${SUBSCRIPTION_ID}" --sdk-auth --only-show-errors | base64 ${w0}) +AZURE_CREDENTIALS=$(echo $SERVICE_PRINCIPAL | base64 -d) + +## Set the Azure Credentials as a secret in the repository +gh secret --repo $(gh repo set-default --view) set "AZURE_CREDENTIALS" -b"${AZURE_CREDENTIALS}" +gh variable --repo $(gh repo set-default --view) set "SERVICE_PRINCIPAL_NAME_WLS_VM" -b"${SERVICE_PRINCIPAL_NAME_WLS_VM}" + +echo "Execute azure-credential-setup.sh - End--------------------------------------------" diff --git a/.github/resource/azure-credential-teardown-wls-aks.sh b/.github/resource/azure-credential-teardown-wls-aks.sh new file mode 100644 index 000000000..8e85df681 --- /dev/null +++ b/.github/resource/azure-credential-teardown-wls-aks.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -Eeuo pipefail + +echo "Execute azure-credential-teardown.sh - Start------------------------------------------" + +gh secret --repo $(gh repo set-default --view) delete "AZURE_CREDENTIALS" +SERVICE_PRINCIPAL_NAME_WLS_AKS=$(gh variable --repo $(gh repo set-default --view) get "SERVICE_PRINCIPAL_NAME_WLS_AKS") +az ad sp delete --id $(az ad sp list --display-name $SERVICE_PRINCIPAL_NAME_WLS_AKS --query "[].appId" -o tsv| tr -d '\r\n') + +echo "Execute azure-credential-teardown.sh - End--------------------------------------------" diff --git a/.github/resource/azure-credential-teardown-wls-vm.sh b/.github/resource/azure-credential-teardown-wls-vm.sh new file mode 100644 index 000000000..520873f85 --- /dev/null +++ b/.github/resource/azure-credential-teardown-wls-vm.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -Eeuo pipefail + +echo "Execute azure-credential-teardown.sh - Start------------------------------------------" + +gh secret --repo $(gh repo set-default --view) delete "AZURE_CREDENTIALS" +SERVICE_PRINCIPAL_NAME_WLS_VM=$(gh variable --repo $(gh repo set-default --view) get "SERVICE_PRINCIPAL_NAME_WLS_VM") +az ad sp delete --id $(az ad sp list --display-name $SERVICE_PRINCIPAL_NAME_WLS_VM --query "[].appId" -o tsv| tr -d '\r\n') + +echo "Execute azure-credential-teardown.sh - End--------------------------------------------" diff --git a/.github/resource/credentials-params-setup.sh b/.github/resource/credentials-params-setup.sh new file mode 100644 index 000000000..b30bd6e11 --- /dev/null +++ b/.github/resource/credentials-params-setup.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +# ANSI color codes +RED='\033[0;31m' +NC='\033[0m' # No Color + +echo "setup-credentials.sh - Start" + +# Function to print error messages in red +print_error() { + local message=$1 + echo -e "${RED}Error: ${message}${NC}" +} + +check_parameters() { + echo "Checking parameters..." + local has_empty_value=0 + + while IFS= read -r line; do + name=$(echo "$line" | yq -r '.name') + value=$(echo "$line" | yq -r '.value') + + if [ -z "$value" ] || [ "$value" == "null" ]; then + print_error "The parameter '$name' has an empty/null value. Please provide a valid value." + has_empty_value=1 + break + else + echo "Name: $name, Value: $value" + fi + done < <(yq eval -o=json '.[]' "$param_file" | jq -c '.') + + echo "return $has_empty_value" + return $has_empty_value +} + +# Function to set values from YAML +set_values() { + echo "Setting values..." + yq eval -o=json '.[]' "$param_file" | jq -c '.' | while read -r line; do + name=$(echo "$line" | jq -r '.name') + value=$(echo "$line" | jq -r '.value') + gh secret --repo $(gh repo set-default --view) set "$name" -b"${value}" + done +} + +# Main script execution +main() { + if check_parameters; then + echo "All parameters are valid." + set_values + else + echo "Parameter check failed. Exiting." + exit 1 + fi + + echo "setup-credentials.sh - Finish" +} + +# Run the main function +main diff --git a/.github/resource/credentials-params-teardown.sh b/.github/resource/credentials-params-teardown.sh new file mode 100644 index 000000000..a014c4761 --- /dev/null +++ b/.github/resource/credentials-params-teardown.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +echo "teardown-credentials.sh - Start" + +# remove param the json +yq eval -o=json '.[]' "$param_file" | jq -c '.' | while read -r line; do + name=$(echo "$line" | jq -r '.name') + value=$(echo "$line" | jq -r '.value') + gh secret --repo $(gh repo set-default --view) delete "$name" +done + +echo "teardown-credentials.sh - Finish" diff --git a/.github/resource/credentials-params-wls-aks.yaml b/.github/resource/credentials-params-wls-aks.yaml new file mode 100644 index 000000000..c5c5784e8 --- /dev/null +++ b/.github/resource/credentials-params-wls-aks.yaml @@ -0,0 +1,23 @@ +# This file contains the parameters for the credentials used in the workflows. +- name: ORC_SSOUSER + value: "" + description: "Oracle single sign-on userid." +- name: ORC_SSOPSW + value: "" + description: "Password for Oracle single sign-on userid." +- name: WDT_RUNTIMEPSW + value: "" + description: "Password for WebLogic Server and Runtime Deployment Tooling encryption." +- name: WLS_PSW + value: ${WDT_RUNTIMEPSW} + description: "Password for WebLogic Server and Runtime Deployment Tooling encryption." +# parameters for the credentials used in the workflows with default values. +- name: WLS_USERNAME + value: "weblogic" + description: "WebLogic Server user name." +- name: DB_PASSWORD + value: "Secret123!" + description: "Password for the database" +- name: LOCATION + value: "eastus" + description: "Location of the resource group" diff --git a/.github/resource/credentials-params-wls-vm.yaml b/.github/resource/credentials-params-wls-vm.yaml new file mode 100644 index 000000000..33dc568f8 --- /dev/null +++ b/.github/resource/credentials-params-wls-vm.yaml @@ -0,0 +1,35 @@ +# This file contains the parameters for the credentials used in the workflows. +- name: OTN_USERID + value: "" + description: Oracle single sign-on userid. +- name: OTN_PASSWORD + value: "" + description: Password for Oracle single sign-on userid. +- name: WLS_PSW + value: "" + description: Password for WebLogic Server. +# Git credentials +- name: USER_EMAIL + value: "" + description: User Email of GitHub acount to access GitHub repository. +- name: USER_NAME + value: "" + description: User name of GitHub account +- name: GIT_TOKEN + value: "" + description: GitHub token to access GitHub repository. +# parameters for the credentials used in the workflows with default values. +- name: LOCATION + value: "eastus" + description: Location of the resource group +# Optional parameters: +# if you want to use optional parameters, please uncomment the following lines +#- name: ELK_URI +# value: "" +# description: URI (hostname:port) for Elastic server, leave blank if you don't want to integrate ELK. +#- name: ELK_USER_NAME +# value: "" +# description: Account password for Elastic server, leave blank if you don't want to integrate ELK. +#- name: ELK_PSW +# value: "" +# description: Account password for Elastic server, leave blank if you don't want to integrate ELK. diff --git a/.github/resource/pre-check.sh b/.github/resource/pre-check.sh new file mode 100644 index 000000000..533c230db --- /dev/null +++ b/.github/resource/pre-check.sh @@ -0,0 +1,68 @@ +# Check environment and tools required to run the script + +# ANSI color codes +GREEN='\033[0;32m' +NC='\033[0m' # No Color + +## Check if the required tools are installed and logged in +echo -e "${GREEN}To run this script, you need to have the following tools installed:${NC}" +echo -e "${GREEN}1. yq${NC}" +echo -e "${GREEN}2. Github CLI (gh)${NC}" +echo -e "${GREEN}3. Azure CLI (az)${NC}" +echo -e "${GREEN}And you need to be logged in to GitHub CLI (gh), and Azure CLI (az).${NC}" + +echo "Checking if the required tools are installed..." +echo "Checking progress started..." + +if ! command -v yq &> /dev/null; then + echo "Check required tools and environment failed." + echo "yq is not installed. Please install it to proceed." + exit 1 +fi +echo "1/6...yq is installed." + +if ! command -v jq &> /dev/null; then + echo "Check required tools and environment failed." + echo "jq is not installed. Please install it to proceed." + exit 1 +fi +echo "2/6...jq is installed." + +# Check gh installed +if ! command -v gh &> /dev/null; then + echo "Check required tools and environment failed." + echo "GitHub CLI (gh) is not installed. Please install it to proceed." + exit 1 +fi +echo "3/6...GitHub CLI (gh) is installed." + + +# Check if the GitHub CLI (gh) is logged in +if ! gh auth status &> /dev/null; then + echo "Check required tools and environment failed." + echo "You are not logged in to GitHub CLI (gh). Please log in with `gh auth login` to proceed." + exit 1 +fi +echo "4/6...You are logged in to GitHub CLI (gh)." + +# check if az is installed +if ! command -v az &> /dev/null; then + echo "Check required tools and environment failed." + echo "Azure CLI (az) is not installed. Please install it to proceed." + exit 1 +fi +echo "5/6...Azure CLI (az) is installed." + + +# check if az is logged in +if ! az account show &> /dev/null; then + echo "Check required tools and environment failed." + echo "You are not logged in to Azure CLI (az). Please log in with command `az login` to proceed." + exit 1 +fi +echo "6/6...You are logged in to Azure CLI (az)." + +echo "Checking progress completed..." + +echo "Select default repository for this project" +gh repo set-default diff --git a/.github/variables/vm-dependencies.env b/.github/variables/vm-dependencies.env new file mode 100644 index 000000000..3e181d08a --- /dev/null +++ b/.github/variables/vm-dependencies.env @@ -0,0 +1,2 @@ +refArmttk=6b75cb7a3f65234995a2019fcae20a9b2c2d8635 +azCliVersion=2.72.0 diff --git a/.github/workflows/buildWlsAksArtifact.yml b/.github/workflows/buildWlsAksArtifact.yml new file mode 100644 index 000000000..d40dfdb2b --- /dev/null +++ b/.github/workflows/buildWlsAksArtifact.yml @@ -0,0 +1,59 @@ +name: Build WLS on AKS artifact + +on: + workflow_dispatch: + repository_dispatch: + types: [aks-package] + # Sample cURL + # curl --verbose -X POST https://api.github.com/repos//weblogic-azure/dispatches -H 'Accept: application/vnd.github.everest-preview+json' -H 'Authorization: token ' --data '{"event_type": "aks-package"}' + +env: + location: eastus + aksRepoUserName: oracle + aksRepoBranchName: main + +jobs: + preflight: + runs-on: ubuntu-latest + steps: + - name: Get versions of external dependencies + run: | + curl -Lo external-deps-versions.properties https://raw.githubusercontent.com/Azure/azure-javaee-iaas/main/external-deps-versions.properties + source external-deps-versions.properties + echo "azCliVersion=${AZ_CLI_VERSION}" >> $GITHUB_ENV + echo "bicepVersion=${BICEP_VERSION}" >> $GITHUB_ENV + - name: Set up bicep + run: | + curl -Lo bicep https://github.com/Azure/bicep/releases/download/${bicepVersion}/bicep-linux-x64 + chmod +x ./bicep + sudo mv ./bicep /usr/local/bin/bicep + bicep --version + - uses: actions/checkout@v2.3.4 + - name: Set up Maven with GitHub token + uses: ./.github/actions/setupmaven + with: + token: ${{ secrets.GITHUB_TOKEN }} + - name: Download arm-ttk used in partner center pipeline + run: | + wget -O arm-template-toolkit.zip https://aka.ms/arm-ttk-azureapps + unzip arm-template-toolkit.zip -d arm-ttk + - name: Checkout ${{ env.aksRepoUserName }}/weblogic-azure + uses: actions/checkout@v2 + with: + path: weblogic-azure + - name: Build and test weblogic-azure/weblogic-azure-aks + run: mvn -Pbicep -Passembly clean install -Ptemplate-validation-tests --file weblogic-azure/weblogic-azure-aks/pom.xml + - name: Generate artifact file name and path + id: artifact_file + run: | + version=$(mvn -q -Dexec.executable=echo -Dexec.args='${version.wls-on-aks-azure-marketplace}' --file weblogic-azure/pom.xml --non-recursive exec:exec) + artifactName=wls-on-aks-azure-marketplace-$version-arm-assembly + unzip weblogic-azure/weblogic-azure-aks/target/$artifactName.zip -d weblogic-azure/weblogic-azure-aks/target/$artifactName + echo "##[set-output name=artifactName;]${artifactName}" + echo "##[set-output name=artifactPath;]weblogic-azure/weblogic-azure-aks/target/$artifactName" + - name: Archive weblogic-azure/weblogic-azure-aks template + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + if: success() + with: + name: ${{steps.artifact_file.outputs.artifactName}} + path: ${{steps.artifact_file.outputs.artifactPath}} diff --git a/.github/workflows/buildWlsVm4AsArtifact.yml b/.github/workflows/buildWlsVm4AsArtifact.yml new file mode 100644 index 000000000..ff53bc5d3 --- /dev/null +++ b/.github/workflows/buildWlsVm4AsArtifact.yml @@ -0,0 +1,93 @@ +# Copyright (c) 2021, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +name: Build Admin Server VM artifact +on: + repository_dispatch: + types: [vms-admin-package] + workflow_dispatch: + inputs: + pidType: + description: 'Specify which pids to use, oracle or microsoft.' + required: true + default: 'oracle' + + # Sample cURL + # curl --verbose -X POST https://api.github.com/repos//weblogic-azure/dispatches -H 'Accept: application/vnd.github.everest-preview+json' -H 'Authorization: token ' --data '{"event_type": "vms-admin-package", "client_payload": {"pidType": "microsoft"}}' +env: + offerName: "arm-oraclelinux-wls-admin" + repoName: "weblogic-azure" + repoOwner: ${{ github.repository_owner }} + ref: ${{ github.ref_name }} + +jobs: + package: + runs-on: ubuntu-latest + steps: + - name: Setup environment variables + id: setup-env-variables-based-on-dispatch-event + run: | + if [ ${{ github.event_name }} == 'workflow_dispatch' ]; then + pidType=${{ github.event.inputs.pidType }} + else + pidType=${{ github.event.client_payload.pidType }} + fi + + if [ -z "$pidType" ]; then + pidType='microsoft' + fi + + echo "##[set-output name=pidType;]${pidType}" + echo "pidType=${pidType}" >> $GITHUB_ENV + + - uses: actions/checkout@v2.3.4 + - name: Set up Maven with GitHub token + uses: ./.github/actions/setupmaven + with: + token: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/checkout@v2.3.4 + - name: Set dependency reference + uses: ./.github/actions/setvars + with: + varFilePath: ./.github/variables/vm-dependencies.env + - name: Download arm-ttk used in partner center pipeline + run: | + wget -O arm-template-toolkit.zip https://aka.ms/arm-ttk-azureapps + unzip arm-template-toolkit.zip -d arm-ttk + - name: Checkout ${{ env.repoName }} + uses: actions/checkout@v2 + with: + path: ${{ env.repoName }} + + - name: Update utilities path location + run: | + cd ${{env.repoName}}/weblogic-azure-vm/${{ env.offerName }} + find . -name "*.json" | xargs sed -i 's|../../../../utilities|../utilities|g' $1 + - name: Build and test ${{ env.offerName }} using ${{ env.pidType }} pids + run: | + cd ${{env.repoName}}/weblogic-azure-vm/${{ env.offerName }} + pidType=${{ env.pidType }} + if [[ "${pidType}" == "oracle" ]];then + echo "using oracle pid" + mvn -Ptemplate-validation-tests clean install -Dgit.repo.owner=${{ env.repoOwner }} -Dgit.tag=${{ env.ref }} + else + echo "using ms pid" + mvn -Ptemplate-validation-tests clean install -Ddev -Dgit.repo.owner=${{ env.repoOwner }} -Dgit.tag=${{ env.ref }} + fi + + - name: Generate artifact file name and path + id: artifact_file + run: | + version=$(mvn -q -Dexec.executable=echo -Dexec.args='${version.${{ env.offerName }}}' --file weblogic-azure/pom.xml --non-recursive exec:exec) + cd ${{env.repoName}}/weblogic-azure-vm/${{ env.offerName }} + artifactName=${{ env.offerName }}-$version-arm-assembly + unzip target/$artifactName.zip -d target/$artifactName + echo "##[set-output name=artifactName;]${artifactName}-${{ env.pidType }}" + echo "##[set-output name=artifactPath;]${{env.repoName}}/weblogic-azure-vm/${{ env.offerName }}/target/$artifactName" + - name: Archive ${{ env.offerName }} template + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + if: success() + with: + name: ${{steps.artifact_file.outputs.artifactName}} + path: ${{steps.artifact_file.outputs.artifactPath}} + diff --git a/.github/workflows/buildWlsVm4CcArtifact.yml b/.github/workflows/buildWlsVm4CcArtifact.yml new file mode 100644 index 000000000..d8d4a6394 --- /dev/null +++ b/.github/workflows/buildWlsVm4CcArtifact.yml @@ -0,0 +1,94 @@ +#Copyright (c) 2021 Oracle and/or its affiliates. +#Released under the Universal Permissive License v1.0 as shown at +# https://oss.oracle.com/licenses/upl/ + +name: Build Configured Cluster VM artifact +on: + repository_dispatch: + types: [vms-configured-cluster-package] + workflow_dispatch: + inputs: + pidType: + description: 'Specify which pids to use, oracle or microsoft.' + required: true + default: 'oracle' + + # Sample cURL + # curl --verbose -X POST https://api.github.com/repos//weblogic-azure/dispatches -H 'Accept: application/vnd.github.everest-preview+json' -H 'Authorization: token ' --data '{"event_type": "vms-configured-cluster-package", "client_payload": {"pidType": "microsoft"} }' +env: + offerName: "arm-oraclelinux-wls-cluster" + repoName: "weblogic-azure" + repoOwner: ${{ github.repository_owner }} + ref: ${{ github.ref_name }} + +jobs: + package: + runs-on: ubuntu-latest + steps: + - name: Setup environment variables + id: setup-env-variables-based-on-dispatch-event + run: | + if [ ${{ github.event_name }} == 'workflow_dispatch' ]; then + pidType=${{ github.event.inputs.pidType }} + else + pidType=${{ github.event.client_payload.pidType }} + fi + if [ -z "$pidType" ]; then + pidType='microsoft' + fi + + echo "##[set-output name=pidType;]${pidType}" + echo "pidType=${pidType}" >> $GITHUB_ENV + + - uses: actions/checkout@v2.3.4 + - name: Set up Maven with GitHub token + uses: ./.github/actions/setupmaven + with: + token: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/checkout@v2.3.4 + - name: Set dependency reference + uses: ./.github/actions/setvars + with: + varFilePath: ./.github/variables/vm-dependencies.env + - name: Download arm-ttk used in partner center pipeline + run: | + wget -O arm-template-toolkit.zip https://aka.ms/arm-ttk-azureapps + unzip arm-template-toolkit.zip -d arm-ttk + - name: Checkout ${{ env.repoName }} + uses: actions/checkout@v2 + with: + path: ${{ env.repoName }} + + - name: Update utilities path location + run: | + cd ${{env.repoName}}/weblogic-azure-vm/${{ env.offerName }} + find . -name "*.json" | xargs sed -i 's|../../../../../utilities|../utilities|g' $1 + - name: Build and test ${{ env.offerName }} using ${{ env.pidType }} pids + run: | + cd ${{env.repoName}}/weblogic-azure-vm/${{ env.offerName }}/${{ env.offerName }} + pidType=${{ env.pidType }} + if [[ "${pidType}" == "oracle" ]];then + echo "using oracle pid" + mvn -Ptemplate-validation-tests clean install -Dgit.repo.owner=${{ env.repoOwner }} -Dgit.tag=${{ env.ref }} + else + echo "using ms pid" + mvn -Ptemplate-validation-tests clean install -Ddev -Dgit.repo.owner=${{ env.repoOwner }} -Dgit.tag=${{ env.ref }} + fi + + - name: Generate artifact file name and path + id: artifact_file + run: | + version=$(mvn -q -Dexec.executable=echo -Dexec.args='${version.${{ env.offerName }}}' --file weblogic-azure/pom.xml --non-recursive exec:exec) + cd ${{env.repoName}}/weblogic-azure-vm/${{ env.offerName }}/${{ env.offerName }} + artifactName=${{ env.offerName }}-$version-arm-assembly + unzip target/$artifactName.zip -d target/$artifactName + echo "##[set-output name=artifactName;]${artifactName}-${{ env.pidType }}" + echo "##[set-output name=artifactPath;]${{env.repoName}}/weblogic-azure-vm/${{ env.offerName }}/${{ env.offerName }}/target/$artifactName" + - name: Archive ${{ env.offerName }} template + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + if: success() + with: + name: ${{steps.artifact_file.outputs.artifactName}} + path: ${{steps.artifact_file.outputs.artifactPath}} + + diff --git a/.github/workflows/buildWlsVm4DcArtifact.yml b/.github/workflows/buildWlsVm4DcArtifact.yml new file mode 100644 index 000000000..4450d5592 --- /dev/null +++ b/.github/workflows/buildWlsVm4DcArtifact.yml @@ -0,0 +1,90 @@ +#Copyright (c) 2021 Oracle and/or its affiliates. +#Released under the Universal Permissive License v1.0 as shown at +# https://oss.oracle.com/licenses/upl/ + +name: Build Dynamic Cluster VM artifact +on: + repository_dispatch: + types: [vms-dynamic-cluster-package] + workflow_dispatch: + inputs: + pidType: + description: 'Specify which pids to use, oracle or microsoft.' + required: true + default: 'oracle' + + # Sample cURL + # curl --verbose -X POST https://api.github.com/repos//weblogic-azure/dispatches -H 'Accept: application/vnd.github.everest-preview+json' -H 'Authorization: token ' --data '{"event_type": "vms-dynamic-cluster-package", "client_payload": {"pidType": "microsoft"}}' +env: + offerName: "arm-oraclelinux-wls-dynamic-cluster" + repoName: "weblogic-azure" + repoOwner: ${{ github.repository_owner }} + ref: ${{ github.ref_name }} + + +jobs: + package: + runs-on: ubuntu-latest + steps: + - name: Setup environment variables + id: setup-env-variables-based-on-dispatch-event + run: | + if [ ${{ github.event_name }} == 'workflow_dispatch' ]; then + pidType=${{ github.event.inputs.pidType }} + else + pidType=${{ github.event.client_payload.pidType }} + fi + if [ -z "$pidType" ]; then + pidType='microsoft' + fi + + echo "##[set-output name=pidType;]${pidType}" + echo "pidType=${pidType}" >> $GITHUB_ENV + + - uses: actions/checkout@v2.3.4 + - name: Set up Maven with GitHub token + uses: ./.github/actions/setupmaven + with: + token: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/checkout@v2.3.4 + - name: Download arm-ttk used in partner center pipeline + run: | + wget -O arm-template-toolkit.zip https://aka.ms/arm-ttk-azureapps + unzip arm-template-toolkit.zip -d arm-ttk + - name: Checkout ${{ env.repoName }} + uses: actions/checkout@v2 + with: + path: ${{ env.repoName }} + + - name: Update utilities path location + run: | + cd ${{env.repoName}}/weblogic-azure-vm/${{ env.offerName }} + find . -name "*.json" | xargs sed -i 's|../../../../../utilities|../utilities|g' $1 + - name: Build and test ${{ env.offerName }} using ${{ env.pidType }} pids + run: | + cd ${{env.repoName}}/weblogic-azure-vm/${{ env.offerName }}/${{ env.offerName }} + pidType=${{ env.pidType }} + echo ${pidType} + if [[ "${pidType}" == "oracle" ]];then + echo "using oracle pids" + mvn -Ptemplate-validation-tests clean install -Dgit.repo.owner=${{ env.repoOwner }} -Dgit.tag=${{ env.ref }} + else + echo "using ms pids" + mvn -Ptemplate-validation-tests clean install -Ddev -Dgit.repo.owner=${{ env.repoOwner }} -Dgit.tag=${{ env.ref }} + fi + + - name: Generate artifact file name and path + id: artifact_file + run: | + version=$(mvn -q -Dexec.executable=echo -Dexec.args='${version.${{ env.offerName }}}' --file weblogic-azure/pom.xml --non-recursive exec:exec) + cd ${{env.repoName}}/weblogic-azure-vm/${{ env.offerName }}/${{ env.offerName }} + artifactName=${{ env.offerName }}-$version-arm-assembly + unzip target/$artifactName.zip -d target/$artifactName + echo "##[set-output name=artifactName;]${artifactName}-${{ env.pidType }}" + echo "##[set-output name=artifactPath;]${{env.repoName}}/weblogic-azure-vm/${{ env.offerName }}/${{ env.offerName }}/target/$artifactName" + - name: Archive ${{ env.offerName }} template + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + if: success() + with: + name: ${{steps.artifact_file.outputs.artifactName}} + path: ${{steps.artifact_file.outputs.artifactPath}} diff --git a/.github/workflows/buildWlsVm4SnArtifact.yml b/.github/workflows/buildWlsVm4SnArtifact.yml new file mode 100644 index 000000000..3ce879945 --- /dev/null +++ b/.github/workflows/buildWlsVm4SnArtifact.yml @@ -0,0 +1,87 @@ +# Copyright (c) 2021, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +name: Build Single Node VM artifact +on: + repository_dispatch: + types: [vms-single-node-package] + workflow_dispatch: + inputs: + pidType: + description: 'Specify which pids to use, oracle or microsoft.' + required: true + default: 'oracle' + + # Sample cURL + # curl --verbose -X POST https://api.github.com/repos//weblogic-azure/dispatches -H 'Accept: application/vnd.github.everest-preview+json' -H 'Authorization: token ' --data '{"event_type": "vms-single-node-package", "client_payload": {"pidType": "microsoft"}}' +env: + offerName: "arm-oraclelinux-wls" + repoName: "weblogic-azure" + repoOwner: ${{ github.repository_owner }} + ref: ${{ github.ref_name }} + +jobs: + package: + runs-on: ubuntu-latest + steps: + - name: Setup environment variables + id: setup-env-variables-based-on-dispatch-event + run: | + if [ ${{ github.event_name }} == 'workflow_dispatch' ]; then + pidType=${{ github.event.inputs.pidType }} + + else + pidType=${{ github.event.client_payload.pidType }} + + fi + + if [ -z "$pidType" ]; then + pidType='microsoft' + fi + + echo "##[set-output name=pidType;]${pidType}" + echo "pidType=${pidType}" >> $GITHUB_ENV + + - uses: actions/checkout@v2.3.4 + - name: Set up Maven with GitHub token + uses: ./.github/actions/setupmaven + with: + token: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/checkout@v2.3.4 + - name: Download arm-ttk used in partner center pipeline + run: | + wget -O arm-template-toolkit.zip https://aka.ms/arm-ttk-azureapps + unzip arm-template-toolkit.zip -d arm-ttk + - name: Checkout ${{ env.repoName }} + uses: actions/checkout@v2 + with: + path: ${{ env.repoName }} + + - name: Build and test ${{ env.offerName }} using ${{ env.pidType }} pids + run: | + cd ${{env.repoName}}/weblogic-azure-vm/${{ env.offerName }} + pidType=${{ env.pidType }} + if [[ "${pidType}" == "oracle" ]];then + echo "using oracle pid" + mvn -Ptemplate-validation-tests clean install -Dgit.repo.owner=${{ env.repoOwner }} -Dgit.tag=${{ env.ref }} + else + echo "using ms pid" + mvn -Ptemplate-validation-tests clean install -Ddev -Dgit.repo.owner=${{ env.repoOwner }} -Dgit.tag=${{ env.ref }} + fi + + - name: Generate artifact file name and path + id: artifact_file + run: | + cd ${{env.repoName}}/weblogic-azure-vm/${{ env.offerName }} + version=$(mvn -q -Dexec.executable=echo -Dexec.args='${project.version}' --non-recursive exec:exec) + artifactName=${{ env.offerName }}-$version-arm-assembly + unzip target/$artifactName.zip -d target/$artifactName + echo "##[set-output name=artifactName;]${artifactName}-${{ env.pidType }}" + echo "##[set-output name=artifactPath;]${{env.repoName}}/weblogic-azure-vm/${{ env.offerName }}/target/$artifactName" + - name: Archive ${{ env.offerName }} template + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + if: success() + with: + name: ${{steps.artifact_file.outputs.artifactName}} + path: ${{steps.artifact_file.outputs.artifactPath}} + diff --git a/.github/workflows/checkARMVMSize.yml b/.github/workflows/checkARMVMSize.yml new file mode 100644 index 000000000..ac776235d --- /dev/null +++ b/.github/workflows/checkARMVMSize.yml @@ -0,0 +1,110 @@ +name: Check ARM VM Size Changes + +on: + workflow_dispatch: + schedule: + - cron: '0 0 */14 * *' # Runs at midnight (00:00) UTC every 14 days (2 weeks) + +env: + azureCredentials: ${{ secrets.AZURE_CREDENTIALS }} + repoName: "weblogic-azure" + userEmail: ${{ secrets.USER_EMAIL }} + userName: ${{ secrets.USER_NAME }} + GH_TOKEN: ${{ secrets.GIT_TOKEN }} + +jobs: + check-vm-sizes: + if: github.event_name == 'workflow_dispatch' || (github.event_name == 'schedule' && github.repository_owner == 'azure-javaee') + runs-on: ubuntu-latest + steps: + - name: Checkout weblogic-azure + uses: actions/checkout@v2 + with: + path: weblogic-azure + + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ env.azureCredentials }} + + - name: Check for VM size changes + id: check_vm_sizes + run: | + ls -l ${{ env.repoName }} + # Path to the properties file + property_file="${{ env.repoName }}/resources/azure-common.properties" + + # Check if the properties file exists + if [ ! -f "$property_file" ]; then + echo "Properties file '$property_file' not found." + exit 1 + fi + + if ! grep -q '^azure\.armBased\.vmSize\.list=' "$property_file"; then + echo "Line 'azure.armBased.vmSize.list' not found in $property_file." + echo "vm_sizes_changed=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + # Using grep to find the line containing azure.armBased.vmSize.list + vm_size_variable=$(grep '^azure\.armBased\.vmSize\.list=' "$property_file") + vm_size_list=${vm_size_variable#*=} + + # Print the extracted value + echo "$vm_size_list" + + latest_locations=$(az account list-locations --query '[?not_null(metadata.latitude)] .name' -o tsv) + + new_sizes="" + for location in $latest_locations; do + latest_sizes=$(az vm list-sizes --location $location | jq '.[] | select(.name | contains("p")) | .name' | tr -d "\"") + for size in $latest_sizes; do + # if new_sizes does not contain size + if [[ $(echo "[$new_sizes]" | jq '. | index("'${size}'")') == null ]]; then + echo "Add size: ${size}" + if [ -z "$new_sizes" ]; then + new_sizes="\"$size\"" + else + new_sizes="$new_sizes,\"$size\"" + fi + fi + done + done + + if [ ${#new_sizes} -ne ${#vm_size_list} ]; then + echo "VM sizes changed" + echo "vm_sizes_changed=true" >> "$GITHUB_OUTPUT" + else + echo "vm_sizes_changed=false" >> "$GITHUB_OUTPUT" + fi + + echo "Current sizes : $new_sizes" + echo "latest_sizes=\"${new_sizes}\"" >> "$GITHUB_OUTPUT" + + - name: Create PR if changes detected + if: steps.check_vm_sizes.outputs.vm_sizes_changed == 'true' + run: | + # Logic to create a pull request to update the ARM VM sizes configuration file + # Example: Use GitHub CLI or git commands to create a branch and push changes + cd ${{ env.repoName }} + branchName="update-vm-sizes-$(date +%s)" + git config --global user.email "${userEmail}" + git config --global user.name "${userName}" + + git checkout -b ${branchName} + # Use sed to delete the line starting with azure.armBased.vmSize.list= + property_file="resources/azure-common.properties" + sed -i '/^azure\.armBased\.vmSize\.list=/d' "$property_file" + latest_sizes=$(echo ${{ steps.check_vm_sizes.outputs.latest_sizes }} | sed 's/,/","/g') + echo "azure.armBased.vmSize.list=\"$latest_sizes\"" >> "$property_file" + + git add $property_file + git commit -m "Update ARM VM sizes" + git push origin ${branchName} + + # Create a pull request + gh pr create --title "Update ARM VM sizes" \ + --body "Automatic update of ARM VM sizes based on latest changes" \ + --reviewer edburns,galiacheng \ + --base main \ + --head ${branchName} diff --git a/.github/workflows/it-validation-aks.yaml b/.github/workflows/it-validation-aks.yaml new file mode 100644 index 000000000..1147412bf --- /dev/null +++ b/.github/workflows/it-validation-aks.yaml @@ -0,0 +1,46 @@ +name: IT Validation for AKS +run-name: Running validation workflows with plan:${{ github.event_name == 'schedule' && 'plan-aks' || inputs.it_plan }} + +on: + schedule: + - cron: '0 6 * * 1' # Every Monday at 06:00 UTC + workflow_dispatch: + inputs: + it_plan: + description: 'Path to the validation plan file' + required: true + type: choice + options: + - plan-aks + default: plan-aks + +jobs: + execute-validation: + runs-on: ubuntu-latest + outputs: + results: ${{ steps.it-validation.outputs.results }} + report_url: ${{ steps.it-validation.outputs.report_url }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set validation plan file + id: set-plan-file + run: | + case "${{ inputs.it_plan || 'plan-aks' }}" in + plan-aks) + IT_FILE=".github/it/validation-plan-aks.json" + ;; + *) + echo "Unknown plan option: ${{ inputs.it_plan }}" + exit 1 + ;; + esac + echo "it_file=$IT_FILE" >> $GITHUB_OUTPUT + + - name: Execute IT Validation + id: it-validation + uses: ./.github/actions/it + with: + it_file: ${{ steps.set-plan-file.outputs.it_file }} + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/it-validation-build.yaml b/.github/workflows/it-validation-build.yaml new file mode 100644 index 000000000..5700d1d7c --- /dev/null +++ b/.github/workflows/it-validation-build.yaml @@ -0,0 +1,46 @@ +name: IT Validation for Build +run-name: Running validation workflows with plan:${{ github.event_name == 'schedule' && 'plan-build' || inputs.it_plan }} + +on: + schedule: + - cron: '0 2 * * *' # Runs daily at 2:00 AM UTC + workflow_dispatch: + inputs: + it_plan: + description: 'Path to the validation plan file' + required: true + type: choice + options: + - plan-build + default: plan-build + +jobs: + execute-validation: + runs-on: ubuntu-latest + outputs: + results: ${{ steps.it-validation.outputs.results }} + report_url: ${{ steps.it-validation.outputs.report_url }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set validation plan file + id: set-plan-file + run: | + case "${{ inputs.it_plan || 'plan-build' }}" in + plan-build) + IT_FILE=".github/it/validation-plan-build.json" + ;; + *) + echo "Unknown plan option: ${{ inputs.it_plan }}" + exit 1 + ;; + esac + echo "it_file=$IT_FILE" >> $GITHUB_OUTPUT + + - name: Execute IT Validation + id: it-validation + uses: ./.github/actions/it + with: + it_file: ${{ steps.set-plan-file.outputs.it_file }} + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/it-validation-vm-admin.yaml b/.github/workflows/it-validation-vm-admin.yaml new file mode 100644 index 000000000..45eff4ab5 --- /dev/null +++ b/.github/workflows/it-validation-vm-admin.yaml @@ -0,0 +1,46 @@ +name: IT Validation for VM Admin +run-name: Running validation workflows with plan:${{ github.event_name == 'schedule' && 'plan-vm-admin' || inputs.it_plan }} + +on: + schedule: + - cron: '0 1 * * 1' # Every Monday at 01:00 UTC + workflow_dispatch: + inputs: + it_plan: + description: 'Path to the validation plan file' + required: true + type: choice + options: + - plan-vm-admin + default: plan-vm-admin + +jobs: + execute-validation: + runs-on: ubuntu-latest + outputs: + results: ${{ steps.it-validation.outputs.results }} + report_url: ${{ steps.it-validation.outputs.report_url }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set validation plan file + id: set-plan-file + run: | + case "${{ inputs.it_plan || 'plan-vm-admin' }}" in + plan-vm-admin) + IT_FILE=".github/it/validation-plan-vm-admin.json" + ;; + *) + echo "Unknown plan option: ${{ inputs.it_plan }}" + exit 1 + ;; + esac + echo "it_file=$IT_FILE" >> $GITHUB_OUTPUT + + - name: Execute IT Validation + id: it-validation + uses: ./.github/actions/it + with: + it_file: ${{ steps.set-plan-file.outputs.it_file }} + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/it-validation-vm-cluster.yaml b/.github/workflows/it-validation-vm-cluster.yaml new file mode 100644 index 000000000..86e0820ad --- /dev/null +++ b/.github/workflows/it-validation-vm-cluster.yaml @@ -0,0 +1,46 @@ +name: IT Validation for VM Cluster +run-name: Running validation workflows with plan:${{ github.event_name == 'schedule' && 'plan-vm-cluster' || inputs.it_plan }} + +on: + schedule: + - cron: '0 11 * * 1' # Runs Every Monday at 11:00 UTC + workflow_dispatch: + inputs: + it_plan: + description: 'Path to the validation plan file' + required: true + type: choice + options: + - plan-vm-cluster + default: plan-vm-cluster + +jobs: + execute-validation: + runs-on: ubuntu-latest + outputs: + results: ${{ steps.it-validation.outputs.results }} + report_url: ${{ steps.it-validation.outputs.report_url }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set validation plan file + id: set-plan-file + run: | + case "${{ inputs.it_plan || 'plan-vm-cluster' }}" in + plan-vm-cluster) + IT_FILE=".github/it/validation-plan-vm-cluster.json" + ;; + *) + echo "Unknown plan option: ${{ inputs.it_plan }}" + exit 1 + ;; + esac + echo "it_file=$IT_FILE" >> $GITHUB_OUTPUT + + - name: Execute IT Validation + id: it-validation + uses: ./.github/actions/it + with: + it_file: ${{ steps.set-plan-file.outputs.it_file }} + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/it-validation-vm-dynamic-cluster.yaml b/.github/workflows/it-validation-vm-dynamic-cluster.yaml new file mode 100644 index 000000000..a7ed8e3c2 --- /dev/null +++ b/.github/workflows/it-validation-vm-dynamic-cluster.yaml @@ -0,0 +1,46 @@ +name: IT Validation for VM Dynamic Cluster +run-name: Running validation workflows with plan:${{ github.event_name == 'schedule' && 'plan-vm-dynamic-cluster' || inputs.it_plan }} + +on: + schedule: + - cron: '0 15 * * 1' # Runs Every Monday at 15:00 UTC + workflow_dispatch: + inputs: + it_plan: + description: 'Path to the validation plan file' + required: true + type: choice + options: + - plan-vm-dynamic-cluster + default: plan-vm-dynamic-cluster + +jobs: + execute-validation: + runs-on: ubuntu-latest + outputs: + results: ${{ steps.it-validation.outputs.results }} + report_url: ${{ steps.it-validation.outputs.report_url }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set validation plan file + id: set-plan-file + run: | + case "${{ inputs.it_plan || 'plan-vm-dynamic-cluster' }}" in + plan-vm-dynamic-cluster) + IT_FILE=".github/it/validation-plan-vm-dynamic-cluster.json" + ;; + *) + echo "Unknown plan option: ${{ inputs.it_plan }}" + exit 1 + ;; + esac + echo "it_file=$IT_FILE" >> $GITHUB_OUTPUT + + - name: Execute IT Validation + id: it-validation + uses: ./.github/actions/it + with: + it_file: ${{ steps.set-plan-file.outputs.it_file }} + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/newtag.yml b/.github/workflows/newtag.yml new file mode 100644 index 000000000..c605d2235 --- /dev/null +++ b/.github/workflows/newtag.yml @@ -0,0 +1,151 @@ +name: New Tag +on: + workflow_dispatch: + inputs: + tagname: + description: 'Specify Tag name to create/update.' + required: true + default: '2021-12-10-01-Q4' + ref: + description: 'Specify Git Ref if needed.' + required: false + default: 'refs/heads/main' + repository_dispatch: + types: [gh-pages-newtag] + # sample cURL + # curl --verbose -X POST https://api.github.com/repos//weblogic-azure/dispatches -H 'Accept: application/vnd.github.everest-preview+json' -H 'Authorization: token ' --data '' + # sample + # {"event_type": "gh-pages-newtag", "client_payload": {"tagname": "2021-12-09-02-Q4", "ref": "refs/heads/main" }} + +env: + tagbranch: "tagbranch" + gitToken: ${{ secrets.GIT_TOKEN }} + repoName: "weblogic-azure" + userEmail: ${{ secrets.USER_EMAIL }} + userName: ${{ secrets.USER_NAME }} + repoOwner: ${{ github.repository_owner }} + +jobs: + newtag: + runs-on: ubuntu-latest + steps: + - name: Setup environment variables + id: setup-env-variables-based-on-dispatch-event + run: | + if [ ${{ github.event_name }} == 'workflow_dispatch' ]; then + tagname=${{ github.event.inputs.tagname }} + ref=${{ github.event.inputs.ref }} + else + tagname=${{ github.event.client_payload.tagname }} + ref=${{ github.event.client_payload.ref }} + fi + + if [ -z "$tagname" ]; then + tagname=${userName}`date +%m%d` + fi + + if [ -z "$ref" ]; then + ref='refs/heads/main' + fi + + echo "##[set-output name=tagname;]${tagname}" + echo "##[set-output name=ref;]${ref}" + echo "tagname=${tagname}" >> $GITHUB_ENV + echo "ref=${ref}" >> $GITHUB_ENV + - uses: actions/checkout@v2.3.4 + - name: Set up Maven with GitHub token + uses: ./.github/actions/setupmaven + with: + token: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/checkout@v2.3.4 + - name: Set dependency reference + uses: ./.github/actions/setvars + with: + varFilePath: ./.github/variables/vm-dependencies.env + - name: Get versions of external dependencies + id: get-external-dependencies-version + run: | + curl -Lo external-deps-versions.properties https://raw.githubusercontent.com/Azure/azure-javaee-iaas/main/external-deps-versions.properties + source external-deps-versions.properties + echo "bicepVersion=${BICEP_VERSION}" >> $GITHUB_ENV + - name: Checkout ${{ env.repoName }} + uses: actions/checkout@v2 + with: + path: ${{ env.repoName }} + ref: ${{ env.ref }} + token: ${{ env.gitToken }} + - name: Checkout arm-ttk + uses: actions/checkout@v2 + with: + repository: Azure/arm-ttk + path: arm-ttk + ref: ${{ env.refArmttk }} + - name: Set up bicep + run: | + curl -Lo bicep https://github.com/Azure/bicep/releases/download/${bicepVersion}/bicep-linux-x64 + chmod +x ./bicep + sudo mv ./bicep /usr/local/bin/bicep + bicep --version + - name: Build ${{ env.repoName }} + run: | + cd ${{ env.repoName }} + mvn -Ptemplate-validation-tests clean install --file weblogic-azure-vm/pom.xml -Dgit.repo.owner=${{ env.repoOwner }} -Dgit.tag=${{ env.ref }} + + mvn -Ptemplate-validation-tests -Pbicep clean install --file weblogic-azure-aks/pom.xml -Dgit.repo.owner=${{ env.repoOwner }} -Dgit.tag=${{ env.ref }} + ls weblogic-azure-aks/target/bicep + bicep build weblogic-azure-aks/target/bicep/mainTemplate.bicep --outfile weblogic-azure-aks/src/main/arm/mainTemplate.json + bicep build weblogic-azure-aks/target/bicep/modules/setupDBConnection.bicep --outfile weblogic-azure-aks/src/main/arm/dbTemplate.json + bicep build weblogic-azure-aks/target/bicep/modules/updateWebLogicApplications.bicep --outfile weblogic-azure-aks/src/main/arm/updateAppTemplate.json + + - name: Create new tag + run: | + cd ${{ env.repoName }} + + git config --global core.longpaths true + git config --global user.email $userEmail + git config --global user.name $userName + + authGitPath=https://$gitToken@github.com/${GITHUB_REPOSITORY}.git + + echo "Create tag branch" + remoteBranches=$(git ls-remote --heads) + echo ${remoteBranches} + if [[ -n `echo ${remoteBranches} | grep "${tagbranch}"` ]]; then + git push ${authGitPath} --delete ${tagbranch} -f + fi + + if [[ -n `git branch --all | grep "${tagbranch}"` ]]; then + git branch -D ${tagbranch} + fi + + git checkout -b ${tagbranch} + + # replace pids + list=$(find weblogic-azure-vm -name "*.json" | grep "\/target\/") + for file in ${list}; do + sourcePath=$(echo "$file" | sed "s:target:src/main:g") + if test -f "$sourcePath"; then + echo "Replace ${sourcePath} with ${file}" + cp -f $file $sourcePath + fi + done + + git status + git add --all + git commit -m "hard code pids" + git fetch --unshallow + git push ${authGitPath} ${tagbranch} -f + + # remove existing tag + if [[ -n `git ls-remote --tags | grep "${tagname}"` ]]; then + git push ${authGitPath} --delete ${tagname} -f + fi + + # create new tag + git tag ${tagname} + git push ${authGitPath} ${tagname} -f + git remote add upstream $gitToken@github.com:oracle/weblogic-azure.git + # ignore the error if cannot push, but log it + push_upstream_ignore_failure () { echo "push upstream result: $?" return 0; } + git push upstream ${tagname} -f || push_upstream_ignore_failure + git push ${authGitPath} --delete ${tagbranch} -f diff --git a/.github/workflows/setup-for-wls-aks.sh b/.github/workflows/setup-for-wls-aks.sh new file mode 100644 index 000000000..50a147246 --- /dev/null +++ b/.github/workflows/setup-for-wls-aks.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +################################################ +# This script is invoked by a human who: +# - has done az login. +# - can create repository secrets in the github repo from which this file was cloned. +# - has the gh client >= 2.0.0 installed. +# - has yq 4.x installed. +# +# This script initializes the repo from which this file is was cloned +# with the necessary secrets to run the workflows. +# Steps to run the Script: +# 1. Run az login. +# 2. Run gh auth login. +# 3. Clone the repository. +# 4. Prepare the .github/resource/credentials-params-wls-aks.yaml file with the required parameters. +# 5. Run the script with the following command: +# ``` +# cd .github/workflows +# bash setup-for-wls-aks.sh +# ``` +# 6. The script will set the required secrets in the repository. +# 7. Check the repository secrets to verify that the secrets are set. +################################################ + +set -Eeuo pipefail + +source ../resource/pre-check.sh +## Set environment variables +export param_file="../resource/credentials-params-wls-aks.yaml" +source ../resource/credentials-params-setup.sh +source ../resource/azure-credential-setup-wls-aks.sh diff --git a/.github/workflows/setup-for-wls-vm.sh b/.github/workflows/setup-for-wls-vm.sh new file mode 100644 index 000000000..1cb3d71eb --- /dev/null +++ b/.github/workflows/setup-for-wls-vm.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +################################################ +# This script is invoked by a human who: +# - has done az login. +# - can create repository secrets in the github repo from which this file was cloned. +# - has the gh client >= 2.0.0 installed. +# - has yq 4.x installed. +# +# This script initializes the repo from which this file is was cloned +# with the necessary secrets to run the workflows. +# Steps to run the Script: +# 1. Run az login. +# 2. Run gh auth login. +# 3. Clone the repository. +# 4. Prepare the .github/resource/credentials-params-wls-vm.yaml file with the required parameters. +# 5. Run the script with the following command: +# ``` +# cd .github/workflows +# bash setup-for-wls-vm.sh +# ``` +# 6. The script will set the required secrets in the repository. +# 7. Check the repository secrets to verify that the secrets are set. +################################################ + +set -Eeuo pipefail + +source ../resource/pre-check.sh +## Set environment variables +export param_file="../resource/credentials-params-wls-vm.yaml" +source ../resource/credentials-params-setup.sh +source ../resource/azure-credential-setup-wls-vm.sh diff --git a/.github/workflows/setupWlsAksDependency.yml b/.github/workflows/setupWlsAksDependency.yml new file mode 100644 index 000000000..72f87d3d4 --- /dev/null +++ b/.github/workflows/setupWlsAksDependency.yml @@ -0,0 +1,108 @@ +name: Setup DB and Storage Account + +on: + workflow_dispatch: + # Sample cURL + # curl --verbose -X POST https://api.github.com/repos//weblogic-azure/dispatches -H 'Accept: application/vnd.github.everest-preview+json' -H 'Authorization: token ' --data '{"event_type": "aks-deploy-dependency"}' + repository_dispatch: + types: [aks-deploy-dependency] + +env: + azureCredentials: ${{ secrets.AZURE_CREDENTIALS }} + location: eastus + dbAdminUser: weblogic + dbPassword: ${{ secrets.DB_PASSWORD }} + dbName: wlsdb${{ github.run_id }}${{ github.run_number }} + dbServerName: weblogicdb + resourceGroupForDB: wlsd-db-${{ github.run_id }}-${{ github.run_number }} + resourceGroupForStorageAccount: wlsd-sa-${{ github.run_id }}-${{ github.run_number }} + storageAccountName: wlsdsa${{ github.run_id }}${{ github.run_number }} + storageContainerName: wlsdcon${{ github.run_id }}${{ github.run_number }} + +jobs: + deploy-db: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2.3.4 + - name: Set AZ CLI Version + id: set-az-cli-version + uses: ./.github/actions/setvars + with: + varFilePath: ./.github/variables/vm-dependencies.env + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ env.azureCredentials }} + - name: Create Resource Group + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + echo "create resource group" ${{ env.resourceGroupForDB }} + az group create --verbose --name ${{ env.resourceGroupForDB }} --location ${{ env.location }} + + - uses: actions/checkout@v2.3.4 + - name: Set up PostgreSQL Flexible Server that allows access from Azure services + uses: ./.github/actions/createPostgresqlFlexibleServer + with: + dbAdminUser: ${{ env.dbAdminUser }} + dbName: ${{ env.dbName }} + dbPassword: ${{ env.dbPassword }} + dbServerName: ${{ env.dbServerName }} + location: ${{ env.location }} + resourceGroupName: ${{ env.resourceGroupForDB }} + deploy-storage-account: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2.3.4 + - name: Set AZ CLI Version + id: set-az-cli-version + uses: ./.github/actions/setvars + with: + varFilePath: ./.github/variables/vm-dependencies.env + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ env.azureCredentials }} + - name: Create Resource Group + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + echo "create resource group" ${{ env.resourceGroupForStorageAccount }} + az group create --verbose --name ${{ env.resourceGroupForStorageAccount }} --location ${{ env.location }} + - name: Create Storage Account + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + az storage account create --name ${{ env.storageAccountName }} \ + --resource-group ${{ env.resourceGroupForStorageAccount }} \ + --location ${{ env.location }} \ + --sku Standard_LRS \ + --kind StorageV2 + - name: Create Storage Container + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + az storage container create -n ${{ env.storageContainerName }} --account-name ${{ env.storageAccountName }} + format-db-sa-parameters-for-integration-test: + needs: [deploy-storage-account, deploy-db] + runs-on: ubuntu-latest + steps: + - name: Generate integration-test parameter json + id: artifact_file + run: | + cat <integration-test-data.txt + # sample request + curl --verbose -X POST https://api.github.com/repos/${{ github.repository_owner }}/weblogic-azure/dispatches -H 'Accept: application/vnd.github.everest-preview+json' -H 'Authorization: token ' --data '' + # copy the JSON as + {"event_type": "aks-integration-test-without-dependency-creation", "client_payload": {"gitUserNameForArtifactsLocation": "${{ github.repository_owner }}", "testBranchNameForArtifactsLocation": "${{ github.ref }}", "isForDemo": "false", "disambiguationSuffix": "${{ github.run_id }}", "storageAccountName": "${{ env.storageAccountName }}", "storageContainerName": "${{ env.storageContainerName }}", "dbName": "${{ env.dbName }}"}} + EOF + - name: Archive integration-test-data.txt + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + if: success() + with: + name: integration-test-data + path: integration-test-data.txt diff --git a/.github/workflows/syncupWithUpstream.yml b/.github/workflows/syncupWithUpstream.yml new file mode 100644 index 000000000..35c9df677 --- /dev/null +++ b/.github/workflows/syncupWithUpstream.yml @@ -0,0 +1,31 @@ +name: Merge upstream branches for WLS on AKS +on: + workflow_dispatch: + # Sample cURL + # curl --verbose -X POST https://api.github.com/repos//weblogic-azure/dispatches -H 'Accept: application/vnd.github.everest-preview+json' -H 'Authorization: token ' --data '{"event_type": "aks-upstream-sync"}' + repository_dispatch: + types: [aks-upstream-sync] +env: + userName: ${{ secrets.USER_NAME }} + userEmail: ${{ secrets.USER_EMAIL }} + gitToken: ${{ secrets.GIT_TOKEN }} +jobs: + merge: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + token: ${{ env.gitToken }} + - name: Merge upstream + run: | + git config --global user.name ${{ env.userName }} + git config --global user.email ${{ env.userEmail }} + + # "git checkout main" is unnecessary, already here by default + git pull --unshallow + + git remote add upstream https://github.com/oracle/weblogic-azure.git + git fetch upstream + + git merge --no-edit upstream/main + git push origin main diff --git a/.github/workflows/teardown-for-wls-aks.sh b/.github/workflows/teardown-for-wls-aks.sh new file mode 100644 index 000000000..25fada69b --- /dev/null +++ b/.github/workflows/teardown-for-wls-aks.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +################################################ +# This script is invoked by a human who: +# - can remove repository secrets in the github repo from which this file was cloned. +# - has the gh client >= 2.0.0 installed. +# - has yq 4.x installed. +# +# This script initializes the repo from which this file is was cloned +# with the necessary secrets to run the workflows. +# Steps to run the Script: +# 1. Run gh auth login. +# 2. Clone the repository. +# 3. Run the script with the following command: +# ``` +# cd .github/workflows +# bash teardown-for-wls-aks.sh +# ``` +# 4. The script will remove the required secrets in the repository. +# 5. Check the repository secrets to verify that the secrets are removed. +################################################ + +set -Eeuo pipefail + +source ../resource/pre-check.sh +## Set environment variables +export param_file="../resource/credentials-params-wls-aks.yaml" +source ../resource/credentials-params-teardown.sh +source ../resource/azure-credential-teardown-wls-aks.sh diff --git a/.github/workflows/teardown-for-wls-vm.sh b/.github/workflows/teardown-for-wls-vm.sh new file mode 100644 index 000000000..f05889971 --- /dev/null +++ b/.github/workflows/teardown-for-wls-vm.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +################################################ +# This script is invoked by a human who: +# - can remove repository secrets in the github repo from which this file was cloned. +# - has the gh client >= 2.0.0 installed. +# - has yq 4.x installed. +# +# This script initializes the repo from which this file is was cloned +# with the necessary secrets to run the workflows. +# Steps to run the Script: +# 1. Run gh auth login. +# 2. Clone the repository. +# 3. Run the script with the following command: +# ``` +# cd .github/workflows +# bash teardown-for-wls-vm.sh +# ``` +# 4. The script will remove the required secrets in the repository. +# 5. Check the repository secrets to verify that the secrets are removed. +################################################ + +set -Eeuo pipefail + +source ../resource/pre-check.sh +## Set environment variables +export param_file="../resource/credentials-params-wls-vm.yaml" +source ../resource/credentials-params-teardown.sh +source ../resource/azure-credential-teardown-wls-vm.sh diff --git a/.github/workflows/testWlsAksWithDependencyCreation.yml b/.github/workflows/testWlsAksWithDependencyCreation.yml new file mode 100644 index 000000000..e2a249565 --- /dev/null +++ b/.github/workflows/testWlsAksWithDependencyCreation.yml @@ -0,0 +1,550 @@ +name: Test WLS on AKS with Dependency creation +run-name: Test WLS on AKS with Dependency creation with `db`:${{ inputs.databaseType }} + +on: + workflow_dispatch: + inputs: + isForDemo: + description: 'If set to true, resources will not be deleted' + required: true + default: 'false' + vmSize: + description: 'The VM size for the AKS pool' + required: true + default: Standard_D2s_v3 + location: + description: 'The location for the resources' + required: true + default: centralus + databaseType: + description: 'Database connection' + required: true + default: 'postgresql(flexible)' + type: choice + options: + - postgresql(flexible) + - postgresql-passwordless(flexible) + configurations_for_it: + description: "JSON string of environment variables used for IT" + required: false + default: '{}' + # sample cURL + # curl --verbose -X POST https://api.github.com/repos//weblogic-azure/dispatches -H 'Accept: application/vnd.github.everest-preview+json' -H 'Authorization: token ' --data '{"event_type": "aks-integration-test-with-dependency-creation", "client_payload": {"isForDemo": "false"}}' + repository_dispatch: + types: [aks-integration-test-with-dependency-creation,integration-test-all] + +env: + azureCredentials: ${{ secrets.AZURE_CREDENTIALS }} + resourceGroupForWlsAks: wlsd-aks-${{ github.run_id }}-${{ github.run_number }} + dbAdminUser: weblogic + dbPassword: ${{ secrets.DB_PASSWORD }} + dbName: wlsdb${{ github.run_id }}${{ github.run_number }} + dbServerName: db${{ github.run_id }}${{ github.run_number }} + uamiName: uami${{ github.run_id }}${{ github.run_number }} + ocrSSOUser: ${{ secrets.ORC_SSOUSER }} + ocrSSOPSW: ${{ secrets.ORC_SSOPSW }} + wdtRuntimePassword: ${{ secrets.WDT_RUNTIMEPSW}} + wlsUserName: ${{ secrets.WLS_USERNAME }} + wlsPassword: ${{ secrets.WLS_PSW }} + resourceGroupForDB: wlsd-db-${{ github.repository_owner }}-${{ github.run_id }}-${{ github.run_number }} + resourceGroupForStorageAccount: wlsd-sa-${{ github.run_id }}-${{ github.run_number }} + storageAccountName: wlsdsa${{ github.run_id }}${{ github.run_number }} + storageContainerName: wlsdcon${{ github.run_id }}${{ github.run_number }} + wlsImageTag: "14.1.2.0-generic-jdk17-ol9" + +jobs: + preflight: + outputs: + artifactName: ${{steps.artifact_file.outputs.artifactName}} + isForDemo: ${{ steps.setup-env-variables-based-on-dispatch-event.outputs.isForDemo }} + azCliVersion: ${{steps.set-az-cli-version.outputs.azCliVersion}} + vmSize: ${{ steps.setup-env-variables-based-on-dispatch-event.outputs.vmSize }} + location: ${{ steps.setup-env-variables-based-on-dispatch-event.outputs.location }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2.3.4 + - name: Set AZ CLI Version and save in variable azCliVersion + uses: ./.github/actions/setvars + with: + varFilePath: ./.github/variables/vm-dependencies.env + - name: Output Az CLi version + id: set-az-cli-version + run: | + echo "azCliVersion=${azCliVersion}" >> $GITHUB_OUTPUT + - name: Get versions of external dependencies + id: get-external-dependencies-version + run: | + curl -Lo external-deps-versions.properties https://raw.githubusercontent.com/Azure/azure-javaee-iaas/main/external-deps-versions.properties + source external-deps-versions.properties + echo "bicepVersion=${BICEP_VERSION}" >> $GITHUB_ENV + echo "refArmttk=${ARM_TTK_REFERENCE}" >> $GITHUB_ENV + - name: Setup environment variables + id: setup-env-variables-based-on-dispatch-event + run: | + location=centralus # default value + if [ ${{ github.event_name }} == 'workflow_dispatch' ]; then + isForDemo=${{ github.event.inputs.isForDemo }} + vmSize=${{ github.event.inputs.vmSize }} + location=${{ github.event.inputs.location }} + else + isForDemo=${{ github.event.client_payload.isForDemo }} + vmSize=${{ github.event.client_payload.vmSize }} + location=${{ github.event.client_payload.location }} + fi + + echo "##[set-output name=isForDemo;]${isForDemo}" + echo "##[set-output name=vmSize;]${vmSize}" + echo "##[set-output name=location;]${location}" + + echo "isForDemo=${isForDemo}" >> $GITHUB_ENV + echo "vmSize=${vmSize}" >> $GITHUB_ENV + echo "location=${location}" >> $GITHUB_ENV + - uses: actions/checkout@v2.3.4 + - name: Set up Maven with GitHub token + uses: ./.github/actions/setupmaven + with: + token: ${{ secrets.GITHUB_TOKEN }} + - name: Set up bicep + run: | + curl -Lo bicep https://github.com/Azure/bicep/releases/download/${bicepVersion}/bicep-linux-x64 + chmod +x ./bicep + sudo mv ./bicep /usr/local/bin/bicep + bicep --version + - name: Checkout arm-ttk + uses: actions/checkout@v2 + with: + repository: Azure/arm-ttk + path: arm-ttk + ref: ${{ env.refArmttk }} + - name: Checkout weblogic-azure + uses: actions/checkout@v2 + with: + path: weblogic-azure + - name: Build and test weblogic-azure/weblogic-azure-aks + run: mvn -Pbicep -Passembly clean install -Ptemplate-validation-tests --file weblogic-azure/weblogic-azure-aks/pom.xml + - name: Generate artifact file name and path + id: artifact_file + run: | + version=$(mvn -q -Dexec.executable=echo -Dexec.args='${version.wls-on-aks-azure-marketplace}' --file weblogic-azure/pom.xml --non-recursive exec:exec) + artifactName=wls-on-aks-azure-marketplace-$version-arm-assembly + unzip weblogic-azure/weblogic-azure-aks/target/$artifactName.zip -d weblogic-azure/weblogic-azure-aks/target/$artifactName + echo "##[set-output name=artifactName;]${artifactName}" + echo "##[set-output name=artifactPath;]weblogic-azure/weblogic-azure-aks/target/$artifactName" + - name: Archive weblogic-azure/weblogic-azure-aks template + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + if: success() + with: + name: ${{steps.artifact_file.outputs.artifactName}} + path: ${{steps.artifact_file.outputs.artifactPath}} + + deploy-storage-account: + needs: preflight + runs-on: ubuntu-latest + steps: + - name: Get AZ CLI Version + run: | + echo "azCliVersion=${{needs.preflight.outputs.azCliVersion}}" >> $GITHUB_ENV + echo "location=${{needs.preflight.outputs.location}}" >> $GITHUB_ENV + - name: Checkout Azure-Samples/cargotracker-wls-aks + uses: actions/checkout@v2 + with: + repository: Azure-Samples/cargotracker-wls-aks + path: cargotracker + - uses: actions/setup-java@v4 + with: + distribution: 'microsoft' + java-version: '11' + - run: mvn clean install -PweblogicOnAks --file cargotracker/pom.xml + - name: Query version string for deployment verification + run: | + PROPERTY_FILE="cargotracker/target/cargo-tracker/WEB-INF/classes/org/eclipse/cargotracker/messages.properties" + PROP_KEY=versionString + deployVersion=$(cat $PROPERTY_FILE | grep "$PROP_KEY" | cut -d '=' -f 2) + echo "deployVersion=${deployVersion}" >> $GITHUB_ENV + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ env.azureCredentials }} + - name: Create Resource Group + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + echo "create resource group" ${{ env.resourceGroupForStorageAccount }} + az group create --verbose --name ${{ env.resourceGroupForStorageAccount }} --location $location + - name: Create Storage Account + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + az storage account create --name ${{ env.storageAccountName }} \ + --resource-group ${{ env.resourceGroupForStorageAccount }} \ + --location $location \ + --sku Standard_LRS \ + --kind StorageV2 + - name: Create Storage Container + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + az storage container create -n ${{ env.storageContainerName }} --account-name ${{ env.storageAccountName }} + - name: Upload built web app war file + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + az storage blob upload --account-name ${{ env.storageAccountName }} --container-name ${{ env.storageContainerName }} --file cargotracker/target/cargo-tracker.war --name cargo-tracker.war + deploy-wls-on-aks: + needs: [deploy-storage-account, preflight] + runs-on: ubuntu-latest + env: ${{ fromJson(inputs.configurations_for_it) }} + steps: + - name: Get AZ CLI Version + run: | + echo "azCliVersion=${{needs.preflight.outputs.azCliVersion}}" >> $GITHUB_ENV + echo "location=${{needs.preflight.outputs.location}}" >> $GITHUB_ENV + - name: Checkout weblogic-azure + uses: actions/checkout@v4 + with: + path: weblogic-azure + - name: Download artifact for deployment + uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1 + with: + name: ${{needs.preflight.outputs.artifactName}} + path: ${{needs.preflight.outputs.artifactName}} + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ env.azureCredentials }} + - name: Query web app blob url and set to env + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + sasTokenValidTime=3600 + expiryData=$(( `date +%s`+${sasTokenValidTime})) + sasEnd=`date -d@"$expiryData" -u '+%Y-%m-%dT%H:%MZ'` + sasToken=$(az storage account generate-sas \ + --permissions r \ + --account-name ${{ env.storageAccountName }} \ + --services b \ + --resource-types sco \ + --expiry $sasEnd -o tsv) + cargoTrackerBlobUrl=$(az storage blob url \ + --container-name ${{ env.storageContainerName }} \ + --name cargo-tracker.war \ + --account-name ${{ env.storageAccountName }} \ + --sas-token ${sasToken} -o tsv) + + echo "cargoTrackerBlobUrl=${cargoTrackerBlobUrl}" >> $GITHUB_ENV + - name: Create Resource Group + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + echo "create resource group" ${{ env.resourceGroupForWlsAks }} + az group create --verbose --name ${{ env.resourceGroupForWlsAks }} --location $location + - name: Checkout Azure-Samples/cargotracker-wls-aks + uses: actions/checkout@v2 + with: + repository: Azure-Samples/cargotracker-wls-aks + path: cargotracker + + - name: Provision Azure Vnet + id: vnet-provision + if: ${{ env.newOrExistingVnetForApplicationGateway == 'existing' }} + run: | + echo "Provisioning Azure Vnet with subnet" + az network vnet create \ + --resource-group ${{ env.resourceGroupForWlsAks }} \ + --name ${{ env.vnetForApplicationGateway.name }} \ + --address-prefix 10.0.0.0/28 \ + --subnet-name ${{ env.vnetForApplicationGateway.subnets.gatewaySubnet.name }} \ + --subnet-prefix 10.0.0.0/29 + + - name: Create Database Resource Group + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + echo "create database resource group" ${{ env.resourceGroupForDB }} + az group create --verbose --name ${{ env.resourceGroupForDB }} --location $location + + - name: Provision database + id: database-provision + uses: ./weblogic-azure/.github/actions/database-provision + with: + databaseType: ${{ inputs.databaseType }} + resourceGroup: ${{ env.resourceGroupForDB }} + uamiName: ${{ env.uamiName }} + location: $location + dbInstanceName: ${{ env.dbServerName }} + dbPassword: ${{ env.dbPassword }} + databaseName: ${{ env.dbName }} + dbAdminUser: ${{ env.dbAdminUser }} + + - name: Get database parameters + id: database-parameters + uses: ./weblogic-azure/.github/actions/database-parameters + with: + databaseType: ${{ inputs.databaseType }} + uamiId: ${{ steps.database-provision.outputs.uamiId }} + serverHost: ${{ steps.database-provision.outputs.serverHost }} + dbInstanceName: ${{ env.dbServerName }} + databaseName: ${{ env.dbName }} + dbAdminUser: ${{ env.dbAdminUser }} + + - name: Prepare parameter file + run: | + if ${{ env.createAKSCluster == 'false' }}; then + echo "Deploy with an existing AKS cluster" + export createAKSCluster=false + # the env aksClusterName is set in the `validation-plan-aks.json` file. + export aksClusterName=${{ env.aksClusterName }} + export aksClusterRGName=${{ env.resourceGroupForWlsAks }} + else + echo "Deploy with a new AKS cluster" + export createAKSCluster=true + export aksClusterName="aks-cluster-${{ github.run_id }}-${{ github.run_number }}" + export aksClusterRGName=${{ env.resourceGroupForWlsAks }} + fi + + if ${{ env.enableAppGWIngress == 'false' }}; then + echo "Application Gateway Ingress Controller is disabled" + export enableAppGWIngress=false + else + echo "Application Gateway Ingress Controller is enabled" + export enableAppGWIngress=true + fi + + # prepare parameters for vnet and application gateway + export newOrExistingVnetForApplicationGateway=${{ env.newOrExistingVnetForApplicationGateway }} + export vnetForApplicationGateway=${{ env.vnetForApplicationGateway.name }} + export vnetRGNameForApplicationGateway=${{ env.resourceGroupForWlsAks }} + + echo "generate parameter file" + export databaseType='${{ steps.database-parameters.outputs.databaseType }}' + export enableDB=${{ steps.database-parameters.outputs.enableDB }} + export enablePswlessConnection=${{ steps.database-parameters.outputs.enablePswlessConnection }} + export dsConnectionURL='${{ steps.database-parameters.outputs.dsConnectionURL }}' + export dbUser='${{ steps.database-parameters.outputs.dbUser }}' + export dbIdentity='${{ steps.database-parameters.outputs.dbIdentity }}' + export dbPassword=${{ env.dbPassword }} + export wlsImageTag=${{ env.wlsImageTag }} + + export gitUserName=${{ github.repository_owner }} + export testbranchName=${{ github.sha }} + export appPackageUrls=${cargoTrackerBlobUrl} + + export location=${location} + export ocrSSOPSW=${ocrSSOPSW} + export ocrSSOUser=${ocrSSOUser} + export wdtRuntimePassword=${wdtRuntimePassword} + export wlsPassword=${wlsPassword} + export wlsUserName=${wlsUserName} + export vmSize=${{ needs.preflight.outputs.vmSize }} + + echo "Generating parameter file..." + envsubst < "./weblogic-azure/weblogic-azure-aks/src/test/parameters-deploy-template.json" > "./weblogic-azure/weblogic-azure-aks/src/test/parameters-deploy-${{ github.job }}.json" + + - name: Archive parameters-deploy.json + uses: actions/upload-artifact@v4.6.2 + if: success() + with: + name: parameters-deploy.json + path: ./weblogic-azure/weblogic-azure-aks/src/test/parameters-deploy-${{ github.job }}.json + + - name: Provision AKS Cluster as an existing cluster for deployment + if: ${{ env.createAKSCluster == 'false' }} + run: | + # the value of **createAKSCluster** is `false`, which means the offer won't create a new AKS cluster, but use an existing one. + # in order to simulate the same behavior as the offer, we need to create a new AKS cluster. + + az feature register \ + --namespace "Microsoft.ContainerService" \ + --name "AppGatewayWithOverlayPreview" + az provider register --namespace Microsoft.ContainerService + + az aks create \ + -n ${{ env.aksClusterName }} \ + -g ${{ env.resourceGroupForWlsAks }} \ + --enable-managed-identity \ + --network-plugin azure \ + --load-balancer-sku standard \ + --generate-ssh-keys + + - name: Deploy WebLogic Server Cluster Domain offer + id: deploy-wls-cluster + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + artifactName=${{ needs.preflight.outputs.artifactName }} + az deployment group create \ + --verbose \ + --resource-group ${{ env.resourceGroupForWlsAks }} \ + --name wls-on-aks \ + --parameters @weblogic-azure/weblogic-azure-aks/src/test/parameters-deploy-${{ github.job }}.json \ + --template-file ${artifactName}/mainTemplate.json + + + - name: Query Application Gateway URL + run: | + if ${{ env.enableAppGWIngress == 'false' }}; then + echo skipping current step as Application Gateway Ingress Controller is disabled + exit 0 + fi + + appgatewayname=$(az resource list --resource-group ${{ env.resourceGroupForWlsAks }} --query "[?type=='Microsoft.Network/applicationGateways'].name|[0]" -o tsv) + echo $appgatewayname + publicIpAddressId=$(az network application-gateway show --resource-group ${{ env.resourceGroupForWlsAks }} --name ${appgatewayname} --query frontendIPConfigurations[0].publicIPAddress.id -o tsv) + echo $publicIpAddressId + appGatewayURL=$(az network public-ip show --resource-group ${{ env.resourceGroupForWlsAks }} --ids ${publicIpAddressId} --query dnsSettings.fqdn -o tsv) + echo $appGatewayURL + echo "appGatewayURL=${appGatewayURL}" >> $GITHUB_ENV + - name: Verify Cargo Tracker is deployed as expected + run: | + if ${{ env.enableAppGWIngress == 'false' }}; then + echo skipping current step as Application Gateway Ingress Controller is disabled + exit 0 + fi + + echo "Verifying Cargo Tracker is deployed as expected" + curl --verbose http://${{ env.appGatewayURL }}/cargo-tracker/ + response=$(curl --write-out '%{http_code}' --silent --output /dev/null http://${{ env.appGatewayURL }}/cargo-tracker/) + echo "$response" + if [ "$response" -ne 200 ]; then + echo "Cargo Tracker is not accessible" + exit 1 + else + echo "Cargo Tracker is accessible" + fi + - name: Install kubectl + run: | + curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" + curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256" + sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl + kubectl version --client + - name: Connect to AKS cluster + run: | + echo "connect to cluster" + aksClusterName=$(az resource list --resource-group ${{ env.resourceGroupForWlsAks }} --query "[?type=='Microsoft.ContainerService/managedClusters'].name|[0]" -o tsv) + az aks get-credentials --resource-group ${{ env.resourceGroupForWlsAks }} --name $aksClusterName + - name: Generate&Apply configmap + run: | + wlsDomainNS=sample-domain1-ns + wlsConfigmapName=sample-domain1-wdt-config-map + wlsConfigmapJson=cargo-tracker-db.json + modelFilePath=models + mkdir ${modelFilePath} + echo "create configmap" + echo "export exisiting configmap" + kubectl -n ${wlsDomainNS} get configmap ${wlsConfigmapName} -o json >${wlsConfigmapJson} + + echo "query model keys" + keyList=$(cat ${wlsConfigmapJson} | jq '.data | keys[]' | tr -d "\"") + for item in $keyList; do + data=$(cat ${wlsConfigmapJson} | jq ".data[\"${item}\"]") + data=$(echo "${data:1:${#data}-2}") + echo -e "${data}" >${modelFilePath}/${item} + done + + # remove current configmap and create a new one + kubectl -n ${wlsDomainNS} delete configmap ${wlsConfigmapName} + + cp cargotracker/src/test/aks/cargo-tracker-jms.yaml ${modelFilePath}/cargo-tracker-jms.yaml + + kubectl -n ${wlsDomainNS} create configmap ${wlsConfigmapName} \ + --from-file=${modelFilePath} + + kubectl -n ${wlsDomainNS} label configmap ${wlsConfigmapName} \ + weblogic.domainUID=sample-domain1 + restartVersion=$(kubectl -n ${wlsDomainNS} get domain sample-domain1 '-o=jsonpath={.spec.restartVersion}') + # increase restart version + restartVersion=$((restartVersion + 1)) + # record timestamp before apply changes + timestampBeforePatchingDomain=$(date +%s) + # get the replica number + clusterName=$(kubectl get cluster -n ${wlsDomainNS} -o json | jq -r '.items[0].metadata.name') + replicas=$(kubectl -n ${wlsDomainNS} get cluster ${clusterName} -o json | jq '. | .spec.replicas') + echo "append configmap and update restart version" + kubectl -n ${wlsDomainNS} patch domain sample-domain1 \ + --type=json \ + '-p=[{"op": "replace", "path": "/spec/restartVersion", "value": "'${restartVersion}'" }, {"op": "add", "path": "/spec/configuration/model/configMap", "value": "'${wlsConfigmapName}'" }]' + echo "timestampBeforePatchingDomain=${timestampBeforePatchingDomain}" >> $GITHUB_ENV + echo "replicas=${replicas}" >> $GITHUB_ENV + - name: Verify pods are restarted + run: | + # interval of checking pod status. + checkPodStatusInterval=20 + # max attempt to check pod status. + checkPodStatusMaxAttemps=30 + # domain and namespaces + wlsDomainUID="sample-domain1" + wlsDomainNS=${wlsDomainUID}-ns + + updatedPodNum=0 + attempt=0 + + echo $timestampBeforePatchingDomain $appReplicas $wlsDomainUID $checkPodStatusMaxAttemps $checkPodStatusInterval + + while [[ ${updatedPodNum} -le ${appReplicas} ]] && [[ $attempt -le ${checkPodStatusMaxAttemps} ]]; do + echo "attempts ${attempt}" + ret=$(kubectl get pods -n ${wlsDomainNS} -l weblogic.domainUID=${wlsDomainUID} -o json | jq '.items[] | .metadata.creationTimestamp' | tr -d "\"") + + counter=0 + for item in $ret; do + podCreateTimeStamp=$(date -u -d "${item}" +"%s") + echo "pod create time: $podCreateTimeStamp, base time: ${timestampBeforePatchingDomain}" + if [[ ${podCreateTimeStamp} -gt ${timestampBeforePatchingDomain} ]]; then + counter=$((counter + 1)) + fi + done + + updatedPodNum=$counter + echo "Number of new pod: ${updatedPodNum}" + + attempt=$((attempt + 1)) + sleep ${checkPodStatusInterval} + done + + if [[ ${attempt} -gt ${checkPodStatusMaxAttemps} ]]; then + echo "Failed to restart all weblogic server pods. " + exit 1 + fi + cleanup: + needs: [deploy-wls-on-aks, preflight] + if: ${{ always() && needs.preflight.outputs.isForDemo == 'false' }} + runs-on: ubuntu-latest + steps: + - name: Get AZ CLI Version + run: | + echo "azCliVersion=${{needs.preflight.outputs.azCliVersion}}" >> $GITHUB_ENV + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + - name: Delete Storage Account Resource Group + id: delete-sa-resource-group + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + echo "delete... " ${{ env.resourceGroupForStorageAccount }} + az group delete --yes --no-wait --verbose --name ${{ env.resourceGroupForStorageAccount }} + - name: Delete DB Resource Group + id: delete-db-resource-group + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + echo "delete... " ${{ env.resourceGroupForDB }} + az group delete --yes --no-wait --verbose --name ${{ env.resourceGroupForDB }} + - name: Delete AKS Resource Group + id: delete-aks-resource-group + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + echo "delete... " ${{ env.resourceGroupForWlsAks }} + az group delete --yes --no-wait --verbose --name ${{ env.resourceGroupForWlsAks }} diff --git a/.github/workflows/testWlsAksWithoutDependencyCreation.yml b/.github/workflows/testWlsAksWithoutDependencyCreation.yml new file mode 100644 index 000000000..5c9df73dc --- /dev/null +++ b/.github/workflows/testWlsAksWithoutDependencyCreation.yml @@ -0,0 +1,400 @@ +name: Test WLS on AKS without dependency creation + +on: + workflow_dispatch: + inputs: + gitUserNameForArtifactsLocation: + description: 'Replaced into https://raw.githubusercontent.com/#gitUserName#/weblogic-azure/#testbranchName#/weblogic-azure-aks/src/main/arm/' + required: true + default: oracle + testBranchNameForArtifactsLocation: + description: 'Replaced into https://raw.githubusercontent.com/#gitUserName#/weblogic-azure/#testbranchName#/weblogic-azure-aks/src/main/arm/' + required: true + default: main + isForDemo: + description: 'If set to true, resources will not be deleted' + required: true + default: 'false' + storageAccountName: + description: 'Specify storage account of uploading .war file' + required: true + storageContainerName: + description: 'Specify name of storage container within account' + required: true + dbName: + description: 'Name of the database. Get from another pipeline run' + required: true + vmSize: + description: 'The VM size for the AKS pool' + required: true + default: Standard_D2s_v3 + # sample cURL + # curl --verbose -X POST https://api.github.com/repos//weblogic-azure/dispatches -H 'Accept: application/vnd.github.everest-preview+json' -H 'Authorization: token ' --data '' + # sample + # {"event_type": "aks-integration-test-without-dependency-creation", "client_payload": {"gitUserNameForArtifactsLocation": "", "testBranchNameForArtifactsLocation": "", "isForDemo": "false", "storageAccountName": "wlsdsa13971210545", "storageContainerName": "wlsdcon13971210545", "dbName": "wlsdb13971210545"}} + # the request data can be get from setupWlsAksDependency pipeline, please checkout the summary page and download the generated artifact name 'integration-test-data' + repository_dispatch: + types: [aks-integration-test-without-dependency-creation,integration-test-all] + +env: + azureCredentials: ${{ secrets.AZURE_CREDENTIALS }} + location: eastus + dbAdminUser: weblogic + dbPassword: ${{ secrets.DB_PASSWORD }} + dbServerName: weblogicdb + ocrSSOPSW: ${{ secrets.ORC_SSOPSW }} + ocrSSOUser: ${{ secrets.ORC_SSOUSER }} + wdtRuntimePassword: ${{ secrets.WDT_RUNTIMEPSW}} + wlsUserName: ${{ secrets.WLS_USERNAME }} + wlsPassword: ${{ secrets.WLS_PSW }} + +jobs: + preflight: + runs-on: ubuntu-latest + outputs: + artifactName: ${{steps.artifact_file.outputs.artifactName}} + resourceGroupForWlsAks: ${{ steps.setup-env-variables-based-on-dispatch-event.outputs.resourceGroupForWlsAks }} + dbName: ${{ steps.setup-env-variables-based-on-dispatch-event.outputs.dbName }} + storageAccountName: ${{ steps.setup-env-variables-based-on-dispatch-event.outputs.storageAccountName }} + storageContainerName: ${{ steps.setup-env-variables-based-on-dispatch-event.outputs.storageContainerName }} + isForDemo: ${{ steps.setup-env-variables-based-on-dispatch-event.outputs.isForDemo }} + gitUserNameForArtifactsLocation: ${{ steps.setup-env-variables-based-on-dispatch-event.outputs.gitUserNameForArtifactsLocation }} + testBranchNameForArtifactsLocation: ${{ steps.setup-env-variables-based-on-dispatch-event.outputs.testBranchNameForArtifactsLocation }} + azCliVersion: ${{steps.set-az-cli-version.outputs.azCliVersion}} + vmSize: ${{ steps.setup-env-variables-based-on-dispatch-event.outputs.vmSize }} + steps: + - uses: actions/checkout@v2.3.4 + - name: Set AZ CLI Version + uses: ./.github/actions/setvars + with: + varFilePath: ./.github/variables/vm-dependencies.env + - name: Output Az CLi version + id: set-az-cli-version + run: | + echo "azCliVersion=${azCliVersion}" >> $GITHUB_OUTPUT + - name: Get versions of external dependencies + id: get-external-dependencies-version + run: | + curl -Lo external-deps-versions.properties https://raw.githubusercontent.com/Azure/azure-javaee-iaas/main/external-deps-versions.properties + source external-deps-versions.properties + echo "bicepVersion=${BICEP_VERSION}" >> $GITHUB_ENV + echo "refArmttk=${ARM_TTK_REFERENCE}" >> $GITHUB_ENV + - name: Setup environment variables + id: setup-env-variables-based-on-dispatch-event + run: | + if [ ${{ github.event_name }} == 'workflow_dispatch' ]; then + resourceGroupForWlsAks=wlsd-aks-${{ github.repository_owner }}-${{ github.run_id }}-${{ github.run_number }} + dbName=${{ github.event.inputs.dbName }} + storageAccountName=${{ github.event.inputs.storageAccountName }} + storageContainerName=${{ github.event.inputs.storageContainerName }} + isForDemo=${{ github.event.inputs.isForDemo }} + gitUserNameForArtifactsLocation=${{ github.event.inputs.gitUserNameForArtifactsLocation }} + testBranchNameForArtifactsLocation=${{ github.event.inputs.testBranchNameForArtifactsLocation }} + vmSize=${{ github.event.inputs.vmSize }} + else + resourceGroupForWlsAks=wlsd-aks-${{ github.repository_owner }}-${{ github.run_id }}-${{ github.run_number }} + dbName=${{ github.event.client_payload.dbName }} + storageAccountName=${{ github.event.client_payload.storageAccountName }} + storageContainerName=${{ github.event.client_payload.storageContainerName }} + isForDemo=${{ github.event.client_payload.isForDemo }} + gitUserNameForArtifactsLocation=${{ github.event.client_payload.gitUserNameForArtifactsLocation }} + testBranchNameForArtifactsLocation=${{ github.event.client_payload.testBranchNameForArtifactsLocation }} + vmSize=${{ github.event.client_payload.vmSize }} + fi + + echo "##[set-output name=resourceGroupForWlsAks;]${resourceGroupForWlsAks}" + echo "##[set-output name=dbName;]${dbName}" + echo "##[set-output name=storageAccountName;]${storageAccountName}" + echo "##[set-output name=storageContainerName;]${storageContainerName}" + echo "##[set-output name=isForDemo;]${isForDemo}" + echo "##[set-output name=gitUserNameForArtifactsLocation;]${gitUserNameForArtifactsLocation}" + echo "##[set-output name=testBranchNameForArtifactsLocation;]${testBranchNameForArtifactsLocation}" + echo "##[set-output name=vmSize;]${vmSize}" + + echo "resourceGroupForWlsAks=${resourceGroupForWlsAks}" >> $GITHUB_ENV + echo "dbName=${dbName}" >> $GITHUB_ENV + echo "storageAccountName=${storageAccountName}" >> $GITHUB_ENV + echo "storageContainerName=${storageContainerName}" >> $GITHUB_ENV + echo "isForDemo=${isForDemo}" >> $GITHUB_ENV + echo "gitUserNameForArtifactsLocation=${gitUserNameForArtifactsLocation}" >> $GITHUB_ENV + echo "testBranchNameForArtifactsLocation=${testBranchNameForArtifactsLocation}" >> $GITHUB_ENV + echo "vmSize=${vmSize}" >> $GITHUB_ENV + - uses: actions/checkout@v2.3.4 + - name: Set up Maven with GitHub token + uses: ./.github/actions/setupmaven + with: + token: ${{ secrets.GITHUB_TOKEN }} + - name: Set up bicep + run: | + curl -Lo bicep https://github.com/Azure/bicep/releases/download/${bicepVersion}/bicep-linux-x64 + chmod +x ./bicep + sudo mv ./bicep /usr/local/bin/bicep + bicep --version + - name: Checkout arm-ttk + uses: actions/checkout@v2 + with: + repository: Azure/arm-ttk + path: arm-ttk + ref: ${{ env.refArmttk }} + - name: Checkout weblogic-azure + uses: actions/checkout@v2 + with: + path: weblogic-azure + - name: Build and test weblogic-azure/weblogic-azure-aks + run: mvn -Pbicep -Passembly clean install -Ptemplate-validation-tests --file weblogic-azure/weblogic-azure-aks/pom.xml + - name: Generate artifact file name and path + id: artifact_file + run: | + version=$(mvn -q -Dexec.executable=echo -Dexec.args='${version.wls-on-aks-azure-marketplace}' --file weblogic-azure/pom.xml --non-recursive exec:exec) + artifactName=wls-on-aks-azure-marketplace-$version-arm-assembly + unzip weblogic-azure/weblogic-azure-aks/target/$artifactName.zip -d weblogic-azure/weblogic-azure-aks/target/$artifactName + echo "##[set-output name=artifactName;]${artifactName}" + echo "##[set-output name=artifactPath;]weblogic-azure/weblogic-azure-aks/target/$artifactName" + - name: Archive weblogic-azure/weblogic-azure-aks template + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + if: success() + with: + name: ${{steps.artifact_file.outputs.artifactName}} + path: ${{steps.artifact_file.outputs.artifactPath}} + - name: Checkout Azure-Samples/cargotracker-wls-aks + uses: actions/checkout@v2 + with: + repository: Azure-Samples/cargotracker-wls-aks + path: cargotracker + - name: Maven build web app + run: | + mvn clean install -PweblogicOnAks --file cargotracker/pom.xml + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ env.azureCredentials }} + - name: Upload built web app war file + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + az storage blob upload \ + --account-name ${{ env.storageAccountName }} \ + --container-name ${{ env.storageContainerName }} \ + --file cargotracker/target/cargo-tracker.war \ + --name cargo-tracker.war \ + --overwrite + deploy-wls-on-aks: + needs: preflight + runs-on: ubuntu-latest + steps: + - name: Get AZ CLI Version + run: | + echo "azCliVersion=${{needs.preflight.outputs.azCliVersion}}" >> $GITHUB_ENV + - name: Checkout weblogic-azure + uses: actions/checkout@v2 + with: + path: weblogic-azure + - name: Download artifact for deployment + uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1 + with: + name: ${{needs.preflight.outputs.artifactName}} + path: ${{needs.preflight.outputs.artifactName}} + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ env.azureCredentials }} + - name: Query web app blob url and set to env + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + sasTokenValidTime=3600 + expiryData=$(( `date +%s`+${sasTokenValidTime})) + sasEnd=`date -d@"$expiryData" -u '+%Y-%m-%dT%H:%MZ'` + sasToken=$(az storage account generate-sas \ + --permissions r \ + --account-name ${{ needs.preflight.outputs.storageAccountName }} \ + --services b \ + --resource-types sco \ + --expiry $sasEnd -o tsv) + cargoTrackerBlobUrl=$(az storage blob url \ + --container-name ${{ needs.preflight.outputs.storageContainerName }} \ + --name cargo-tracker.war \ + --account-name ${{ needs.preflight.outputs.storageAccountName }} \ + --sas-token ${sasToken} -o tsv) + + echo "cargoTrackerBlobUrl=${cargoTrackerBlobUrl}" >> $GITHUB_ENV + - name: Create Resource Group + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + echo "create resource group" ${{ needs.preflight.outputs.resourceGroupForWlsAks }} + az group create --verbose --name ${{ needs.preflight.outputs.resourceGroupForWlsAks }} --location ${{ env.location }} + - name: Checkout Azure-Samples/cargotracker-wls-aks + uses: actions/checkout@v2 + with: + repository: Azure-Samples/cargotracker-wls-aks + path: cargotracker + - name: Prepare parameter file + run: | + echo "generate parameter file" + bash weblogic-azure/weblogic-azure-aks/src/test/genWlsAksParameters.sh \ + ${{ needs.preflight.outputs.gitUserNameForArtifactsLocation }} \ + ${{ needs.preflight.outputs.testBranchNameForArtifactsLocation }} \ + "${cargoTrackerBlobUrl}" \ + ${dbPassword} \ + ${dbAdminUser} \ + jdbc:postgresql:\/\/${{ needs.preflight.outputs.dbName }}.postgres.database.azure.com:5432\/${{ env.dbServerName }} \ + ${location} \ + ${ocrSSOPSW} \ + ${ocrSSOUser} \ + ${wdtRuntimePassword} \ + ${wlsPassword} \ + ${wlsUserName} \ + ${{ needs.preflight.outputs.vmSize }} \ + weblogic-azure/weblogic-azure-aks/src/test/setupWlsAksParameters.jsonc + - name: Deploy WebLogic Server Cluster Domain offer + id: deploy-wls-cluster + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + artifactName=${{ needs.preflight.outputs.artifactName }} + + az deployment group create \ + --verbose \ + --resource-group ${{ needs.preflight.outputs.resourceGroupForWlsAks }} \ + --name wls-on-aks \ + --parameters @weblogic-azure/weblogic-azure-aks/src/test/setupWlsAksParameters.jsonc \ + --template-file ${artifactName}/mainTemplate.json + - name: Query Application Gateway URL + run: | + appgatewayname=$(az resource list --resource-group ${{ needs.preflight.outputs.resourceGroupForWlsAks }} --query "[?type=='Microsoft.Network/applicationGateways'].name|[0]" -o tsv) + echo $appgatewayname + publicIpAddressId=$(az network application-gateway show --resource-group ${{ needs.preflight.outputs.resourceGroupForWlsAks }} --name ${appgatewayname} --query frontendIPConfigurations[0].publicIPAddress.id -o tsv) + echo $publicIpAddressId + appGatewayURL=$(az network public-ip show --resource-group ${{ needs.preflight.outputs.resourceGroupForWlsAks }} --ids ${publicIpAddressId} --query dnsSettings.fqdn -o tsv) + echo $appGatewayURL + echo "appGatewayURL=${appGatewayURL}" >> $GITHUB_ENV + - name: Verify Cargo Tracker is deployed as expected + run: | + echo "Verifying Cargo Tracker is deployed as expected" + curl --verbose http://${{ env.appGatewayURL }}/cargo-tracker/ + response=$(curl --write-out '%{http_code}' --silent --output /dev/null http://${{ env.appGatewayURL }}/cargo-tracker/) + echo "$response" + if [ "$response" -ne 200 ]; then + echo "Cargo Tracker is not accessible" + exit 1 + else + echo "Cargo Tracker is accessible" + fi + - name: Install kubectl + run: | + curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" + curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256" + sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl + kubectl version --client + - name: Connect to AKS cluster + run: | + echo "connect to cluster" + aksClusterName=$(az resource list --resource-group ${{ needs.preflight.outputs.resourceGroupForWlsAks }} --query "[?type=='Microsoft.ContainerService/managedClusters'].name|[0]" -o tsv) + az aks get-credentials --resource-group ${{ needs.preflight.outputs.resourceGroupForWlsAks }} --name $aksClusterName + - name: Generate&Apply configmap + run: | + wlsDomainNS=sample-domain1-ns + wlsConfigmapName=sample-domain1-wdt-config-map + wlsConfigmapJson=cargo-tracker-db.json + modelFilePath=models + mkdir ${modelFilePath} + echo "create configmap" + echo "export exisiting configmap" + kubectl -n ${wlsDomainNS} get configmap ${wlsConfigmapName} -o json >${wlsConfigmapJson} + + echo "query model keys" + keyList=$(cat ${wlsConfigmapJson} | jq '.data | keys[]' | tr -d "\"") + for item in $keyList; do + data=$(cat ${wlsConfigmapJson} | jq ".data[\"${item}\"]") + data=$(echo "${data:1:${#data}-2}") + echo -e "${data}" >${modelFilePath}/${item} + done + + # remove current configmap and create a new one + kubectl -n ${wlsDomainNS} delete configmap ${wlsConfigmapName} + + cp cargotracker/src/test/aks/cargo-tracker-jms.yaml ${modelFilePath}/cargo-tracker-jms.yaml + + kubectl -n ${wlsDomainNS} create configmap ${wlsConfigmapName} \ + --from-file=${modelFilePath} + + kubectl -n ${wlsDomainNS} label configmap ${wlsConfigmapName} \ + weblogic.domainUID=sample-domain1 + restartVersion=$(kubectl -n ${wlsDomainNS} get domain sample-domain1 '-o=jsonpath={.spec.restartVersion}') + # increase restart version + restartVersion=$((restartVersion + 1)) + # record timestamp before apply changes + timestampBeforePatchingDomain=$(date +%s) + # get the replica number + clusterName=$(kubectl get cluster -n ${wlsDomainNS} -o json | jq -r '.items[0].metadata.name') + replicas=$(kubectl -n ${wlsDomainNS} get cluster ${clusterName} -o json | jq '. | .spec.replicas') + echo "append configmap and update restart version" + kubectl -n ${wlsDomainNS} patch domain sample-domain1 \ + --type=json \ + '-p=[{"op": "replace", "path": "/spec/restartVersion", "value": "'${restartVersion}'" }, {"op": "add", "path": "/spec/configuration/model/configMap", "value": "'${wlsConfigmapName}'" }]' + echo "timestampBeforePatchingDomain=${timestampBeforePatchingDomain}" >> $GITHUB_ENV + echo "replicas=${replicas}" >> $GITHUB_ENV + - name: Verify pods are restarted + run: | + # interval of checking pod status. + checkPodStatusInterval=20 + # max attempt to check pod status. + checkPodStatusMaxAttemps=30 + # domain and namespaces + wlsDomainUID="sample-domain1" + wlsDomainNS=${wlsDomainUID}-ns + + updatedPodNum=0 + attempt=0 + + echo $timestampBeforePatchingDomain $appReplicas $wlsDomainUID $checkPodStatusMaxAttemps $checkPodStatusInterval + + while [[ ${updatedPodNum} -le ${appReplicas} ]] && [[ $attempt -le ${checkPodStatusMaxAttemps} ]]; do + echo "attempts ${attempt}" + ret=$(kubectl get pods -n ${wlsDomainNS} -l weblogic.domainUID=${wlsDomainUID} -o json | jq '.items[] | .metadata.creationTimestamp' | tr -d "\"") + + counter=0 + for item in $ret; do + podCreateTimeStamp=$(date -u -d "${item}" +"%s") + echo "pod create time: $podCreateTimeStamp, base time: ${timestampBeforePatchingDomain}" + if [[ ${podCreateTimeStamp} -gt ${timestampBeforePatchingDomain} ]]; then + counter=$((counter + 1)) + fi + done + + updatedPodNum=$counter + echo "Number of new pod: ${updatedPodNum}" + + attempt=$((attempt + 1)) + sleep ${checkPodStatusInterval} + done + + if [[ ${attempt} -gt ${checkPodStatusMaxAttemps} ]]; then + echo "Failed to restart all weblogic server pods. " + exit 1 + fi + cleanup: + needs: [deploy-wls-on-aks, preflight] + if: ${{ needs.preflight.outputs.isForDemo == 'false' }} + runs-on: ubuntu-latest + steps: + - name: Get AZ CLI Version + run: | + echo "azCliVersion=${{needs.preflight.outputs.azCliVersion}}" >> $GITHUB_ENV + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ env.azureCredentials }} + - name: Delete AKS Resource Group + id: delete-aks-resource-group + uses: azure/CLI@v1 + with: + azcliversion: ${{ env.azCliVersion }} + inlineScript: | + echo "delete... " ${{ needs.preflight.outputs.resourceGroupForWlsAks }} + az group delete --yes --no-wait --verbose --name ${{ needs.preflight.outputs.resourceGroupForWlsAks }} diff --git a/.github/workflows/testWlsVmAdmin.yml b/.github/workflows/testWlsVmAdmin.yml new file mode 100644 index 000000000..ebd99dbba --- /dev/null +++ b/.github/workflows/testWlsVmAdmin.yml @@ -0,0 +1,486 @@ +# Copyright (c) 2021, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +name: Test Admin Server on VM +run-name: Test Admin Server on VM with `db`:${{ inputs.databaseType }} + +on: + workflow_dispatch: + inputs: + location: + description: 'The location for the resources' + required: true + default: centralus + databaseType: + description: 'Database connection' + required: true + default: 'mssqlserver' + type: choice + options: + - none + - mssqlserver + - mssqlserver-passwordless + - postgresql(flexible) + - postgresql-passwordless(flexible) + configurations_for_it: + description: "JSON string of environment variables used for IT" + required: false + default: '{}' + + # Allows you to run this workflow using GitHub APIs + # PERSONAL_ACCESS_TOKEN= + # REPO_NAME=mriccell/weblogic-azure + # curl --verbose -XPOST -u "mriccell:${PERSONAL_ACCESS_TOKEN}" -H "Accept: application/vnd.github.everest-preview+json" -H "Content-Type: application/json" https://api.github.com/repos/${REPO_NAME}/dispatches --data '{"event_type": "test-vm-admin", "client_payload": {"ref": "refs/heads/main"}}' + repository_dispatch: + types: [test-vm-admin,integration-test-all] + +env: + adminConsolePort: 7005 + adminVMName: adminServerVM + adminPassword: ${{ secrets.WLS_PSW }} + dbAdminUser: weblogic + dbName: wlsdb${{ github.run_id }}${{ github.run_number }} + dbServerName: weblogicdb-${{ github.run_id }}-${{ github.run_number }} + uamiName: uami${{ github.run_id }}${{ github.run_number }} + gitToken: ${{ secrets.GIT_TOKEN }} + offerName: arm-oraclelinux-wls-admin + offerPath: weblogic-azure/weblogic-azure-vm/arm-oraclelinux-wls-admin + testbranchName: cicd-${{ github.run_id }}-${{ github.run_number }} + repoName: weblogic-azure + repoOwner: ${{ github.repository_owner }} + resourceGroupPrefix: wls-${{ github.repository_owner }}-${{ github.run_id }}-${{ github.run_number }} + resourceGroupForDependency: wlsd-${{ github.repository_owner }}-${{ github.run_id }}-${{ github.run_number }} + userEmail: ${{ secrets.USER_EMAIL }} + userName: ${{ secrets.USER_NAME }} + wlsPassword: ${{ secrets.WLS_PSW }} + wlsDomainName: adminDomain + wlsUserName: weblogic + ref: ${{ github.ref_name }} + images: | + owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest + owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest + owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest + owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest + owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest + owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest + owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest + owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest + owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest + owls-122140-jdk8-rhel76;Oracle:weblogic-122140-jdk8-rhel76:owls-122140-jdk8-rhel76;latest + owls-141100-jdk8-rhel76;Oracle:weblogic-141100-jdk8-rhel76:owls-141100-jdk8-rhel76;latest + owls-141100-jdk11-rhel76;Oracle:weblogic-141100-jdk11-rhel76:owls-141100-jdk11-rhel76;latest + +jobs: + preflight: + outputs: + location: ${{ steps.setup-env-variables-based-on-dispatch-event.outputs.location }} + artifactName: ${{steps.artifact_file.outputs.artifactName}} + runs-on: ubuntu-latest + steps: + - name: Setup environment variables + id: setup-env-variables-based-on-dispatch-event + run: | + location=eastus # default value + + if [ ${{ github.event_name }} == 'workflow_dispatch' ]; then + location=${{ github.event.inputs.location }} + else + location=${{ github.event.client_payload.location }} + fi + + echo "##[set-output name=location;]${location}" + echo "location=${location}" >> $GITHUB_ENV + - uses: actions/checkout@v2.3.4 + - name: Set up Maven with GitHub token + uses: ./.github/actions/setupmaven + with: + token: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/checkout@v2.3.4 + - name: Set dependency reference + uses: ./.github/actions/setvars + with: + varFilePath: ./.github/variables/vm-dependencies.env + - name: Checkout arm-ttk + uses: actions/checkout@v2 + with: + repository: Azure/arm-ttk + path: arm-ttk + ref: ${{ env.refArmTtk }} + - name: Checkout ${{env.repoOwner}}/${{env.repoName}} + uses: actions/checkout@v2 + with: + repository: ${{env.repoOwner}}/${{env.repoName}} + path: ${{env.repoName}} + - name: Build and test ${{ env.offerName }} + run: | + ls + mvn -Ptemplate-validation-tests clean install -Dgit.repo.owner=${{ env.repoOwner }} -Dgit.tag=${{ env.ref }} --file ${offerPath}/pom.xml + + - name: Checkout ${{env.repoOwner}}/${{env.repoName}} for test + uses: actions/checkout@v2 + with: + repository: ${{env.repoOwner}}/${{env.repoName}} + path: ${{env.repoName}}-dev + - name: Create a new branch with development pids in nestedtemplates + run: | + current=`pwd` + echo "current=${current}" >> $GITHUB_ENV + offerDevPath=${{ env.repoName }}-dev/weblogic-azure-vm/${{env.offerName}} + cd ${offerDevPath}/src/main/arm/nestedtemplates + git config --global core.longpaths true + git config --global user.email $userEmail + git config --global user.name $userName + echo "create branch $testbranchName" + git checkout -b $testbranchName + rm -r -f $current/${offerDevPath}/src/main/arm/nestedtemplates/* + cp -r -f $current/${{ env.offerPath }}/target/arm/nestedtemplates/* $current/${offerDevPath}/src/main/arm/nestedtemplates/ + git status + git commit -a -m "hard code pids" + git push https://$gitToken@github.com/${GITHUB_REPOSITORY}.git -f + + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + - name: Validate deployment templates for different combinations of service integration + id: validate-deployment-templates + run: | + bash ${{ env.offerPath }}/test/scripts/verify-deployments.sh \ + <<< "${{ github.run_id }}${{ github.run_number }} ${location} \ + ${{ env.offerPath }}/target/arm/mainTemplate.json \ + ${GITHUB_REPOSITORY} ${testbranchName} ${{ env.offerPath }}/test/scripts" + + - name: Get version information from pom.xml + id: version + run: | + version=$(mvn -q -Dexec.executable=echo -Dexec.args='${version.${{ env.offerName }}}' --file weblogic-azure/pom.xml --non-recursive exec:exec) + echo "version=${version}" >> $GITHUB_ENV + - name: Print version + run: echo $version + - name: Generate artifact name + run: echo "artifactName=${{ env.offerName }}-$version-arm-assembly" >> $GITHUB_ENV + - name: Print artifact name + run: echo $artifactName + - name: Output artifact name + id: artifact_file + run: echo "##[set-output name=artifactName;]${{ env.offerName }}-$version-arm-assembly" + - name: Generate zip package path + id: artifact_path + run: echo "##[set-output name=artifactPath;]${{ env.offerPath }}/target/$artifactName" + - name: Output artifact path + run: echo $artifactPath + env: + artifactPath: ${{steps.package.outputs.artifactPath}} + - name: Unzip the package as upload action will zip again + run: unzip ${{ env.offerPath }}/target/$artifactName.zip -d ${{ env.offerPath }}/target/$artifactName + + - name: Archive ${{ env.offerName }} template + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + if: success() + with: + name: ${{steps.artifact_file.outputs.artifactName}} + path: ${{steps.artifact_path.outputs.artifactPath}} + + deploy-dependencies: + needs: preflight + runs-on: ubuntu-latest + steps: + - name: Initialize environment variables + run: | + echo "location=${{needs.preflight.outputs.location}}" >> $GITHUB_ENV + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + - name: Create Resource Group + id: create-resource-group + run: | + echo "create resource group" ${{ env.resourceGroupForDependency }} + az group create --verbose --name ${{ env.resourceGroupForDependency }} --location ${location} + - uses: actions/checkout@v2.3.4 + + deploy-weblogic-admin: + needs: [deploy-dependencies, preflight] + runs-on: ubuntu-latest + env: ${{ fromJson(inputs.configurations_for_it) }} + steps: + - name: Initialize environment variables + run: | + echo "location=${{needs.preflight.outputs.location}}" >> $GITHUB_ENV + echo "artifactName=${{ needs.preflight.outputs.artifactName }}" >> $GITHUB_ENV + + - name: Checkout weblogic-azure repository + uses: actions/checkout@v4 + with: + path: ${{env.repoName}} + + - name: Download artifact for deployment + uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1 + with: + name: ${{ needs.preflight.outputs.artifactName }} + path: ${{needs.preflight.outputs.artifactName}} + + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Provision database + id: database-provision + uses: ./weblogic-azure/.github/actions/database-provision + with: + databaseType: ${{ inputs.databaseType }} + resourceGroup: ${{ env.resourceGroupForDependency }} + uamiName: ${{ env.uamiName }} + location: ${{ env.location }} + dbInstanceName: ${{ env.dbServerName }} + dbPassword: ${{ env.wlsPassword }} + databaseName: ${{ env.dbName }} + dbAdminUser: ${{ env.dbAdminUser }} + + - name: Get database parameters + id: database-parameters + uses: ./weblogic-azure/.github/actions/database-parameters + with: + databaseType: ${{ inputs.databaseType }} + uamiId: ${{ steps.database-provision.outputs.uamiId }} + serverHost: ${{ steps.database-provision.outputs.serverHost }} + dbInstanceName: ${{ env.dbServerName }} + databaseName: ${{ env.dbName }} + dbAdminUser: ${{ env.dbAdminUser }} + + - name: Provision Azure Vnet + id: vnet-provision + if: ${{ env.virtualNetworkNewOrExisting == 'existing' }} + run: | + echo "Provisioning Azure Vnet with subnet" + az network vnet create \ + --resource-group ${{ env.resourceGroupForDependency }} \ + --name ${{ env.virtualNetworkName }} \ + --address-prefix 10.0.0.0/28 \ + --subnet-name ${{ env.subnetName }} \ + --subnet-prefix 10.0.0.0/29 + + - name: Try each image until one succeeds + run: | + # Convert multiline string to array + IFS=$'\n' read -d '' -r -a image_array <<< "${{ env.images }}" || true + + success=false + + for image in "${image_array[@]}"; do + if [ -z "$image" ]; then + continue + fi + + echo "::group::Trying image: $image" + + # Set deployment variables for this image + imageUrn="$image" + sku=${imageUrn%%;*} + resourceGroup=$(echo "${resourceGroupPrefix}-${sku}" | sed "s/_//g") + + echo "Deploying with SKU: $sku" + echo "Resource Group: $resourceGroup" + + # Export db variables for envsubst + export databaseType='${{ steps.database-parameters.outputs.databaseType }}' + export enableDB=${{ steps.database-parameters.outputs.enableDB }} + export enablePswlessConnection=${{ steps.database-parameters.outputs.enablePswlessConnection }} + export dsConnectionURL='${{ steps.database-parameters.outputs.dsConnectionURL }}' + export dbUser='${{ steps.database-parameters.outputs.dbUser }}' + export dbIdentity='${{ steps.database-parameters.outputs.dbIdentity }}' + export dbPassword='${{ env.wlsPassword}}' + export dbName='${{ env.dbName }}' + + # Try deployment with this image + if bash -c " + set -e + + # Create Resource Group + echo 'Creating resource group: $resourceGroup' + az group create --verbose --name '$resourceGroup' --location '${location}' + + ## Prepare Vnet parameters + if [ "${{ env.virtualNetworkNewOrExisting }}" == "existing" ]; then + export virtualNetworkResourceGroupName=${{ env.resourceGroupForDependency }} + export virtualNetworkNewOrExisting=${{ env.virtualNetworkNewOrExisting }} + export virtualNetworkName=${{ env.virtualNetworkName }} + export subnetName=${{ env.subnetName }} + else + export virtualNetworkResourceGroupName='$resourceGroup' + export virtualNetworkNewOrExisting="new" + export virtualNetworkName="wls-vnet" + export subnetName="wls-subnet" + fi + + # Export variables for envsubst + export adminPasswordOrKey='${{ env.wlsPassword }}' + export skuUrnVersion='$image' + export wlsdomainname='${{ env.wlsDomainName }}' + export adminVMName='${{ env.adminVMName }}' + export location='${{ env.location }}' + export wlsusername='${{ env.wlsUserName }}' + export wlspassword='${{ env.wlsPassword }}' + export repoPath='${GITHUB_REPOSITORY}' + export testbranchName='${{ env.testbranchName }}' + + echo 'Generating parameter file...' + envsubst < './${{ env.offerPath }}/test/scripts/parameters-deploy-template.json' > './${{ env.offerPath }}/test/parameters-deploy-${{ github.job }}.json' + + # Accept Image Terms + echo 'Accepting terms for image: $image' + rawUrn='$image' + publisherAndName=\$(echo \${rawUrn} | grep -o ';.*:' | sed 's/;//g') + imageVersion=\${rawUrn##*;} + az vm image terms accept --urn \${publisherAndName}$sku:\${imageVersion} + + # Deploy WebLogic Server + echo 'Deploying WebLogic Server...' + az deployment group create \ + --verbose \ + --resource-group '$resourceGroup' \ + --name wls-admin-node \ + --parameters @'./${{ env.offerPath }}/test/parameters-deploy-${{ github.job }}.json' \ + --template-file '${{needs.preflight.outputs.artifactName}}/mainTemplate.json' + + # Get admin VM name + adminVMName=\$(az deployment group show \ + --resource-group '$resourceGroup' \ + --name wls-admin-node \ + --query 'properties.outputs.adminVMName.value' -o tsv) + + # Verify system services + echo 'Verifying WebLogic services...' + message=\$(az vm run-command invoke \ + --resource-group '$resourceGroup' \ + --name \$adminVMName \ + --command-id RunShellScript \ + --scripts @'${{ env.offerPath }}/test/scripts/verify-services.sh' \ + --query value[*].message) + + if [[ \$message == *'not in active (running) state'* ]]; then + echo 'Error: \$message' + exit 1 + fi + + if [ "${{ env.virtualNetworkNewOrExisting }}" == "existing" ]; then + # If using existing VNet, there are some gaps to verify the deployment using following steps. + echo 'skip following steps, only verify the deployment for existing vnet' + exit 0 + fi + + # Configure network security group + echo 'Configuring network security group...' + nsg=\$(az network nsg list \ + --resource-group '$resourceGroup' \ + --query '[0].name' -o tsv) + + az network nsg rule update \ + --resource-group '$resourceGroup' \ + --nsg-name \${nsg} \ + --name WebLogicAdminChannelPort \ + --access Allow \ + --source-address-prefixes 10.0.0.0/24 + + # Get public IP + publicIP=\$(az vm show \ + --resource-group '$resourceGroup' \ + --name \$adminVMName -d \ + --query publicIps -o tsv) + + # Verify WebLogic Server Access + echo 'Verifying WebLogic Server Access...' + bash '${{ env.offerPath }}/test/scripts/verify-wls-access.sh' <<< \"\${publicIP} ${adminConsolePort}\" + + echo 'SUCCESS: All verification steps passed!' + exit 0 + "; then + echo "✅ SUCCESS: WebLogic deployment succeeded with image: $image" + echo "successful_image=$image" >> $GITHUB_ENV + echo "successful_resource_group=$resourceGroup" >> $GITHUB_ENV + success=true + + # Clean up successful deployment + echo "Cleaning up resource group: $resourceGroup" + az group delete --yes --no-wait --verbose --name "$resourceGroup" || true + + break + else + echo "❌ FAILED: WebLogic deployment failed with image: $image, trying next..." + # Clean up failed deployment + echo "Cleaning up failed resource group: $resourceGroup" + az group delete --yes --no-wait --verbose --name "$resourceGroup" || true + fi + echo "::endgroup::" + done + + if [ "$success" = "false" ]; then + echo "💥 All images failed!" + exit 1 + else + echo "🎉 Workflow succeeded with image: ${{ env.successful_image }}" + fi + + cleanup-github-resource: + needs: deploy-weblogic-admin + if: always() + runs-on: ubuntu-latest + steps: + - name: Checkout ${{ env.repoOwner }}/${{ env.repoName }} + uses: actions/checkout@v2 + with: + repository: ${{ env.repoOwner }}/${{ env.repoName }} + path: ${{ env.repoName }} + - name: Delete testing branch + run: | + cd ${{ env.repoName }} + git push https://$gitToken@github.com/${GITHUB_REPOSITORY}.git -f --delete $testbranchName + + cleanup-az-resource: + needs: deploy-weblogic-admin + if: always() + runs-on: ubuntu-latest + steps: + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + - name: Delete DB Resource Group + id: delete-db-resource-group + run: | + echo "delete... " $resourceGroup + az group delete --yes --no-wait --verbose --name ${{ env.resourceGroupForDependency }} + - name: Delete Resource Group + id: delete-resource-group + run: | + echo "delete resource group with prefix:" ${{ env.resourceGroupPrefix }} + az group list --query "[?starts_with(name, '${{ env.resourceGroupPrefix }}')].[name]" -o tsv | xargs -I {} az group delete --name {} --yes --no-wait + + summary: + needs: deploy-weblogic-admin + if: always() + runs-on: ubuntu-latest + steps: + - name: summarize jobs + if: ${{ github.repository_owner == 'wls-eng' }} + run: | + workflow_jobs=$(curl -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/${GITHUB_REPOSITORY}/actions/runs/${{ github.run_id }}/jobs) + critical_job_num=$(echo $workflow_jobs | jq '.jobs | map(select(.name|test("^deploy-weblogic-admin."))) | length') + echo "$critical_job_num" + succeed_critical_job_num=$(echo $workflow_jobs | jq '.jobs | map(select(.conclusion=="success") | select(.name|test("^deploy-weblogic-admin."))) | length') + echo "$succeed_critical_job_num" + failed_job_num="$(($critical_job_num-$succeed_critical_job_num))" + echo $failed_job_num + if (($failed_job_num >= 2));then + echo "too many jobs failed, send notification to Teams" + curl ${{ secrets.MSTEAMS_WEBHOOK }} \ + -H 'Content-Type: application/json' \ + --data-binary @- << EOF + { + "@context":"http://schema.org/extensions", + "@type":"MessageCard", + "text":"$failed_job_num jobs failed in Admin Offer's workflow, please take a look at: https://github.com/${GITHUB_REPOSITORY}/actions/runs/${{ github.run_id }}" + } + EOF + fi diff --git a/.github/workflows/testWlsVmCluster.yml b/.github/workflows/testWlsVmCluster.yml new file mode 100644 index 000000000..451417b08 --- /dev/null +++ b/.github/workflows/testWlsVmCluster.yml @@ -0,0 +1,551 @@ +#Copyright (c) 2021 Oracle and/or its affiliates. +#Released under the Universal Permissive License v1.0 as shown at +# https://oss.oracle.com/licenses/upl/ + +name: Test Configured Cluster on VM +run-name: Test Configured Cluster on VM with `db`:${{ inputs.databaseType }} + +on: + workflow_dispatch: + inputs: + location: + description: 'The location for the resources' + required: true + default: centralus + databaseType: + description: 'Database connection' + required: true + default: 'mssqlserver' + type: choice + options: + - mssqlserver + - mssqlserver-passwordless + - postgresql(flexible) + - postgresql-passwordless(flexible) + configurations_for_it: + description: "JSON string of environment variables used for IT" + required: false + default: '{}' + # Allows you to run this workflow using GitHub APIs + # PERSONAL_ACCESS_TOKEN= + # REPO_NAME=oracle/weblogic-azure/weblogic-azure-vm/arm-oraclelinux-wls-cluster + # curl --verbose -XPOST -u "mriccell:${PERSONAL_ACCESS_TOKEN}" -H "Accept: application/vnd.github.everest-preview+json" -H "Content-Type: application/json" https://api.github.com/repos/${REPO_NAME}/dispatches --data '{"event_type": "test-vm-cluster", "client_payload": {}}' + repository_dispatch: + types: [test-vm-cluster,integration-test-all] + +env: + adminConsolePort: 7001 + adminPassword: ${{ secrets.WLS_PSW }} + dbAdminUser: weblogic + dbName: wlsdb${{ github.run_id }}${{ github.run_number }} + dbServerName: weblogicdb-${{ github.run_id }}-${{ github.run_number }} + uamiName: uami${{ github.run_id }}${{ github.run_number }} + gitEmail: ${{ secrets.USER_EMAIL }} + gitToken: ${{ secrets.GIT_TOKEN }} + gitUserName: ${{ secrets.USER_NAME }} + managedServers: "msp1" + numberOfInstances: 2 + offerName: arm-oraclelinux-wls-cluster + offerPath: weblogic-azure/weblogic-azure-vm/arm-oraclelinux-wls-cluster + repoName: weblogic-azure + repoOwner: ${{ github.repository_owner }} + resourceGroupForDependency: wlsd-${{ github.repository_owner }}-${{ github.run_id }}-${{ github.run_number }} + resourceGroupPrefix: wls-${{ github.repository_owner }}-${{ github.run_id }}-${{ github.run_number }} + testbranchName: cicd-${{ github.run_id }}-${{ github.run_number }} + wlsDomainName: wlsd + wlsPassword: ${{ secrets.WLS_PSW }} + wlsUserName: weblogic + ref: ${{ github.ref_name }} + images: | + owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest + owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest + owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest + owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest + owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest + owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest + owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest + owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest + owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest + owls-122140-jdk8-rhel76;Oracle:weblogic-122140-jdk8-rhel76:owls-122140-jdk8-rhel76;latest + owls-141100-jdk8-rhel76;Oracle:weblogic-141100-jdk8-rhel76:owls-141100-jdk8-rhel76;latest + owls-141100-jdk11-rhel76;Oracle:weblogic-141100-jdk11-rhel76:owls-141100-jdk11-rhel76;latest + +jobs: + preflight: + outputs: + artifactName: ${{steps.artifact_file.outputs.artifactName}} + location: ${{ steps.setup-env-variables-based-on-dispatch-event.outputs.location }} + runs-on: ubuntu-latest + steps: + - name: Setup environment variables + id: setup-env-variables-based-on-dispatch-event + run: | + location=centralus # default value + + if [ ${{ github.event_name }} == 'workflow_dispatch' ]; then + location=${{ github.event.inputs.location }} + else + location=${{ github.event.client_payload.location }} + fi + + echo "##[set-output name=location;]${location}" + echo "location=${location}" >> $GITHUB_ENV + + - uses: actions/checkout@v2.3.4 + - name: Set up Maven with GitHub token + uses: ./.github/actions/setupmaven + with: + token: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/checkout@v2.3.4 + - name: Set dependency reference + uses: ./.github/actions/setvars + with: + varFilePath: ./.github/variables/vm-dependencies.env + - name: Checkout arm-ttk + uses: actions/checkout@v2 + with: + repository: Azure/arm-ttk + path: arm-ttk + ref: ${{ env.refArmttk }} + - name: Checkout ${{env.repoOwner}}/${{env.repoName}} + uses: actions/checkout@v2 + with: + repository: ${{env.repoOwner}}/${{env.repoName}} + path: ${{env.repoName}} + + - name: Build and test ${{ env.offerName }} + run: | + mvn -Ptemplate-validation-tests clean install --file ${offerPath}/pom.xml -Dgit.repo.owner=${{ env.repoOwner }} -Dgit.tag=${{ env.ref }} + - name: Checkout ${{env.repoOwner}}/${{env.repoName}} + uses: actions/checkout@v2 + with: + repository: ${{env.repoOwner}}/${{env.repoName}} + path: ${{env.repoName}}-dev + - name: Create a new branch with development pids in nestedtemplates + run: | + current=`pwd` + echo "current=${current}" >> $GITHUB_ENV + offerDevPath=${{ env.repoName }}-dev/weblogic-azure-vm/${{env.offerName}}/${{env.offerName}} + cd ${offerDevPath}/src/main/arm/nestedtemplates + git config --global core.longpaths true + git config --global user.email $gitEmail + git config --global user.name $gitUserName + echo "create branch $testbranchName" + git checkout -b $testbranchName + rm -r -f $current/${offerDevPath}/src/main/arm/nestedtemplates/* + cp -r -f $current/${offerPath}/${{ env.offerName }}/target/arm/nestedtemplates/* $current/${offerDevPath}/src/main/arm/nestedtemplates/ + git status + git commit -a -m "hard code pids" + git push https://$gitToken@github.com/${GITHUB_REPOSITORY}.git -f + + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + - name: Validate deployment templates for different combinations of service integration + id: validate-deployment-templates + run: | + bash ${{ env.offerPath }}/test/scripts/verify-deployments.sh <<< "${{ github.run_id }}${{ github.run_number }} ${location} \ + ${{ env.offerPath }}/${{ env.offerName }}/target/arm/mainTemplate.json \ + ${GITHUB_REPOSITORY} ${testbranchName} ${{ env.offerPath }}/test/scripts" + + - name: Generate artifact file name and path + id: artifact_file + run: | + version=$(mvn -q -Dexec.executable=echo -Dexec.args='${version.${{ env.offerName }}}' --file weblogic-azure/pom.xml --non-recursive exec:exec) + artifactName=${{ env.offerName }}-$version-arm-assembly + unzip ${{ env.offerPath }}/${{ env.offerName }}/target/$artifactName.zip -d ${{ env.offerPath }}/${{ env.offerName }}/target/$artifactName + echo "##[set-output name=artifactName;]${artifactName}" + echo "##[set-output name=artifactPath;]${{ env.offerPath }}/${{ env.offerName }}/target/$artifactName" + - name: Archive ${{ env.offerName }} template + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + if: success() + with: + name: ${{steps.artifact_file.outputs.artifactName}} + path: ${{steps.artifact_file.outputs.artifactPath}} + + deploy-dependencies: + needs: preflight + runs-on: ubuntu-latest + steps: + - name: Initialize environment variables + run: | + echo "location=${{needs.preflight.outputs.location}}" >> $GITHUB_ENV + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Create Resource Group + run: | + echo "create resource group" ${{ env.resourceGroupForDependency }} + az group create --verbose --name ${{ env.resourceGroupForDependency }} --location ${location} + + deploy-weblogic-cluster: + needs: [deploy-dependencies, preflight] + runs-on: ubuntu-latest + env: ${{ fromJson(inputs.configurations_for_it) }} + steps: + - name: Initialize environment variables + run: | + echo "location=${{needs.preflight.outputs.location}}" >> $GITHUB_ENV + + - name: Checkout weblogic-azure repository + uses: actions/checkout@v4 + with: + path: ${{env.repoName}} + + - name: Download artifact for deployment + uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1 + with: + name: ${{ needs.preflight.outputs.artifactName }} + path: ${{needs.preflight.outputs.artifactName}} + + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Checkout WebLogic-Cafe + id: checkout-webapp + uses: actions/checkout@v2 + with: + repository: azure-javaee/weblogic-on-azure + path: weblogic-on-azure + + - name: Maven build the web app + id: maven-build-webapp + run: | + echo "build the WebLogic Cafe web app" + mvn -DskipTests clean install --file weblogic-on-azure/javaee/weblogic-cafe/pom.xml + + - name: Provision database + id: database-provision + uses: ./weblogic-azure/.github/actions/database-provision + with: + databaseType: ${{ inputs.databaseType }} + resourceGroup: ${{ env.resourceGroupForDependency }} + uamiName: ${{ env.uamiName }} + location: ${{ env.location }} + dbInstanceName: ${{ env.dbServerName }} + dbPassword: ${{ env.wlsPassword }} + databaseName: ${{ env.dbName }} + dbAdminUser: ${{ env.dbAdminUser }} + + - name: Get database parameters + id: database-parameters + uses: ./weblogic-azure/.github/actions/database-parameters + with: + databaseType: ${{ inputs.databaseType }} + uamiId: ${{ steps.database-provision.outputs.uamiId }} + serverHost: ${{ steps.database-provision.outputs.serverHost }} + dbInstanceName: ${{ env.dbServerName }} + databaseName: ${{ env.dbName }} + dbAdminUser: ${{ env.dbAdminUser }} + + - name: Provision Azure Vnet + id: vnet-provision + if: ${{ env.virtualNetworkNewOrExisting == 'existing' }} + run: | + echo "Provisioning Azure Vnet with subnet" + az network vnet create \ + --resource-group ${{ env.resourceGroupForDependency }} \ + --name ${{ env.virtualNetworkName }} \ + --address-prefix 10.0.0.0/23 \ + --subnet-name ${{ env.subnetForCluster }} \ + --subnet-prefix 10.0.0.0/26 + + echo "Provisioning Azure Subnet for App Gateway" + az network vnet subnet create \ + --resource-group ${{ env.resourceGroupForDependency }} \ + --name ${{ env.subnetForAppGateway }} \ + --vnet-name ${{ env.virtualNetworkName }} \ + --address-prefix 10.0.1.0/24 + + - name: Try each image until one succeeds + run: | + # Convert multiline string to array + IFS=$'\n' read -d '' -r -a image_array <<< "${{ env.images }}" || true + + success=false + + for image in "${image_array[@]}"; do + if [ -z "$image" ]; then + continue + fi + + echo "::group::Trying image: $image" + + # Set deployment variables for this image + imageUrn="$image" + sku=${imageUrn%%;*} + resourceGroup=$(echo "${resourceGroupPrefix}-${sku}" | sed "s/_//g") + + echo "Deploying with SKU: $sku" + echo "Resource Group: $resourceGroup" + + # Export db variables for envsubst + export databaseType='${{ steps.database-parameters.outputs.databaseType }}' + export enableDB=${{ steps.database-parameters.outputs.enableDB }} + export enablePswlessConnection=${{ steps.database-parameters.outputs.enablePswlessConnection }} + export dsConnectionURL='${{ steps.database-parameters.outputs.dsConnectionURL }}' + export dbUser='${{ steps.database-parameters.outputs.dbUser }}' + export dbIdentity='${{ steps.database-parameters.outputs.dbIdentity }}' + export dbPassword='${{ env.wlsPassword}}' + export dbName='${{ env.dbName }}' + + # Try deployment with this image + if bash -c " + set -e + + # Create Resource Group + echo 'Creating resource group: $resourceGroup' + az group create --verbose --name '$resourceGroup' --location '${location}' + + ## Prepare parameters for Vnet + if [ "${{ env.virtualNetworkNewOrExisting }}" == "existing" ]; then + export virtualNetworkNewOrExisting=${{ env.virtualNetworkNewOrExisting }} + export virtualNetworkResourceGroupName=${{ env.resourceGroupForDependency }} + export virtualNetworkName=${{ env.virtualNetworkName }} + export subnetForCluster=${{ env.subnetForCluster }} + export subnetForAppGateway=${{ env.subnetForAppGateway }} + else + export virtualNetworkNewOrExisting='new' + export virtualNetworkResourceGroupName='$resourceGroup' + export virtualNetworkName='wlscluster-vnet-cluster' + export subnetForCluster='jboss-subnet-for-cluster' + export subnetForAppGateway='appgateway-subnet' + fi + + export repoPath='${GITHUB_REPOSITORY}' + export testbranchName='${{ env.testbranchName }}' + export location='${{ env.location }}' + export adminPasswordOrKey='${{ env.wlsPassword }}' + export wlsusername='${{ env.wlsUserName }}' + export wlsdomainname='${{ env.wlsDomainName }}' + export skuUrnVersion='$image' + export wlspassword='${{ env.wlsPassword }}' + + echo 'Generating parameter file...' + envsubst < './${{ env.offerPath }}/test/scripts/parameters-deploy-template.json' > './${{ env.offerPath }}/test/parameters-deploy-${{ github.job }}.json' + + # Accept Image Terms + echo 'Accepting terms for image: $image' + rawUrn='$image' + publisherAndName=\$(echo \${rawUrn} | grep -o ';.*:' | sed 's/;//g') + imageVersion=\${rawUrn##*;} + az vm image terms accept --urn \${publisherAndName}$sku:\${imageVersion} + + # Deploy WebLogic Server Cluster Domain offer + echo 'Deploying WebLogic Server Cluster...' + az deployment group create \ + --verbose \ + --resource-group '$resourceGroup' \ + --name wls-cluster-node \ + --parameters @'./${{ env.offerPath }}/test/parameters-deploy-${{ github.job }}.json' \ + --template-file '${{needs.preflight.outputs.artifactName}}/mainTemplate.json' + + if [ "${{ env.virtualNetworkNewOrExisting }}" == "existing" ]; then + # If using existing VNet, there are some gaps to verify the deployment using following steps. + echo 'skip following steps, only verify the deployment for existing vnet' + exit 0 + fi + + # Get admin VM name + echo 'Retrieving admin VM name...' + adminVMName=\$(az deployment group show \ + --resource-group '$resourceGroup' \ + --name wls-cluster-node \ + --query 'properties.outputs.adminVMName.value' -o tsv) + + # Configure network security group + echo 'Configuring network security group...' + nsg=\$(az network nsg list \ + --resource-group '$resourceGroup' \ + --query '[0].name' -o tsv) + + az network nsg rule update \ + --resource-group '$resourceGroup' \ + --nsg-name \${nsg} \ + --name WebLogicAdminChannelPort \ + --access Allow \ + --source-address-prefixes 10.0.0.0/24 + + # Verify system services at admin server + echo 'Verifying WebLogic services at admin server...' + message=\$(az vm run-command invoke \ + --resource-group '$resourceGroup' \ + --name \$adminVMName \ + --command-id RunShellScript \ + --scripts @'${{ env.offerPath }}/test/scripts/verify-admin-services.sh' \ + --query value[*].message) + + if [[ \$message == *'not in active (running) state'* ]]; then + echo 'Error: \$message' + exit 1 + fi + + # Verify wls managed server services + echo 'Verifying WebLogic managed server services...' + managedServerVMNamePrefix=\$(az deployment group show \ + --resource-group '$resourceGroup' \ + --name wls-cluster-node \ + --query 'properties.outputs.managedServerVMNamePrefix.value' -o tsv) + + managedServer1=\"\${managedServerVMNamePrefix}1\" + + message=\$(az vm run-command invoke \ + --resource-group '$resourceGroup' \ + --name \$managedServer1 \ + --command-id RunShellScript \ + --scripts @'${{ env.offerPath }}/test/scripts/verify-node-services.sh' \ + --query value[*].message) + + if [[ \$message == *'not in active (running) state'* ]]; then + echo 'Error: \$message' + exit 1 + fi + + # Get public IP + publicIP=\$(az vm show \ + --resource-group '$resourceGroup' \ + --name \$adminVMName -d \ + --query publicIps -o tsv) + + # Verify WebLogic Server Access + echo 'Verifying WebLogic Server Access...' + bash '${{ env.offerPath }}/test/scripts/verify-wls-access.sh' <<< \"\${publicIP} ${adminConsolePort} $wlsUserName $wlsPassword $managedServers\" + + # Verify WebLogic Managed Server LifeCycle check + echo 'Verifying WebLogic managed server lifecycle...' + bash '${{ env.offerPath }}/test/scripts/verify-servers-lifecycle.sh' <<< \"$wlsUserName ${wlsPassword} \${publicIP} $adminConsolePort $managedServers\" + + # Query appGatewayURL + echo 'Querying app gateway URL...' + appGatewayURL=\$(az deployment group show \ + --resource-group '$resourceGroup' \ + --name wls-cluster-node \ + --query 'properties.outputs.appGatewayURL.value' -o tsv) + + # Checkout WebLogic-Cafe (done outside the loop) + + # Query admin VM DNS + echo 'Querying admin VM DNS...' + adminNicId=\$(az vm show \ + --resource-group '$resourceGroup' \ + --name \$adminVMName \ + --query networkProfile.networkInterfaces[0].id -o tsv) + adminPublicIPId=\$(az network nic show --id \${adminNicId} --query ipConfigurations[0].publicIPAddress.id -o tsv) + adminVMDNS=\$(az network public-ip show \ + --id \"\${adminPublicIPId}\" \ + --query dnsSettings.fqdn -o tsv) + + # Deploy WebLogicCafe app (need to checkout and build first) + echo 'Deploying WebLogic Cafe app...' + timeout 6m sh -c 'until nc -zv \$0 \$1; do echo \"nc rc: \$?\"; sleep 5; done' \${adminVMDNS} ${adminConsolePort} + bash '${{ env.offerPath }}/test/scripts/deploy-webapp.sh' <<< \"$wlsUserName $wlsPassword \${adminVMDNS} ${adminConsolePort}\" + + # Verify WebLogicCafe app deployment + echo 'Verifying WebLogic Cafe app deployment...' + bash '${{ env.offerPath }}/test/scripts/verify-webapp-deployment.sh' <<< \"\${appGatewayURL}\" + + echo 'SUCCESS: All verification steps passed!' + exit 0 + "; then + echo "✅ SUCCESS: WebLogic cluster deployment succeeded with image: $image" + echo "successful_image=$image" >> $GITHUB_ENV + echo "successful_resource_group=$resourceGroup" >> $GITHUB_ENV + success=true + + # Clean up successful deployment + echo "Cleaning up resource group: $resourceGroup" + az group delete --yes --no-wait --verbose --name "$resourceGroup" || true + + break + else + echo "❌ FAILED: WebLogic cluster deployment failed with image: $image, trying next..." + # Clean up failed deployment + echo "Cleaning up failed resource group: $resourceGroup" + az group delete --yes --no-wait --verbose --name "$resourceGroup" || true + fi + echo "::endgroup::" + done + + if [ "$success" = "false" ]; then + echo "💥 All images failed!" + exit 1 + else + echo "🎉 Workflow succeeded with image: ${{ env.successful_image }}" + fi + + cleanup-github-resource: + needs: deploy-weblogic-cluster + if: always() + runs-on: ubuntu-latest + steps: + - name: Checkout ${{ env.repoName }} + uses: actions/checkout@v2 + with: + repository: ${{env.repoOwner}}/${{env.repoName}} + path: ${{ env.repoName }} + - name: Delete testing branch + run: | + cd ${{ env.repoName }} + git push https://$gitToken@github.com/$GITHUB_REPOSITORY.git -f --delete $testbranchName + + cleanup-az-resource: + if: always() + needs: deploy-weblogic-cluster + runs-on: ubuntu-latest + env: ${{ fromJson(inputs.configurations_for_it) }} + steps: + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + - name: Delete resource group for dependency + id: delete-resource-group-for-dependency + run: | + echo "delete... " $resourceGroup + az group delete --yes --no-wait --verbose --name ${{ env.resourceGroupForDependency }} + - name: Delete existing Vnet + id: delete-vnet + if: ${{ env.virtualNetworkNewOrExisting == 'existing' }} + run: | + echo "wait only other resources have been deleted" + sleep 10m + echo "delete vnet" ${{ env.virtualNetworkName }} "in resource group" ${{ env.resourceGroupForDependency }} + az network vnet delete --name ${{ env.virtualNetworkName }} --resource-group ${{ env.resourceGroupForDependency }} + - name: Delete Resource Group + id: delete-resource-group + run: | + echo "delete resource group with prefix:" ${{ env.resourceGroupPrefix }} + az group list --query "[?starts_with(name, '${{ env.resourceGroupPrefix }}')].[name]" -o tsv | xargs -I {} az group delete --name {} --yes --no-wait + + summary: + needs: deploy-weblogic-cluster + if: always() + runs-on: ubuntu-latest + steps: + - name: summarize jobs + if: ${{ github.repository_owner == 'wls-eng' }} + run: | + workflow_jobs=$(curl -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/${GITHUB_REPOSITORY}/actions/runs/${{ github.run_id }}/jobs) + critical_job_num=$(echo $workflow_jobs | jq '.jobs | map(select(.name|test("^deploy-weblogic-cluster$"))) | length') + echo "$critical_job_num" + succeed_critical_job_num=$(echo $workflow_jobs | jq '.jobs | map(select(.conclusion=="success") | select(.name|test("^deploy-weblogic-cluster$"))) | length') + echo "$succeed_critical_job_num" + failed_job_num="$(($critical_job_num-$succeed_critical_job_num))" + echo $failed_job_num + if (($failed_job_num >= 1));then + echo "job failed, send notification to Teams" + curl ${{ secrets.MSTEAMS_WEBHOOK }} \ + -H 'Content-Type: application/json' \ + --data-binary @- << EOF + { + "@context":"http://schema.org/extensions", + "@type":"MessageCard", + "text":"$failed_job_num job failed in Configured Cluster Offer's workflow, please take a look at: https://github.com/${GITHUB_REPOSITORY}/actions/runs/${{ github.run_id }}" + } + EOF + fi diff --git a/.github/workflows/testWlsVmDynamicCluster.yml b/.github/workflows/testWlsVmDynamicCluster.yml new file mode 100644 index 000000000..6bb532d93 --- /dev/null +++ b/.github/workflows/testWlsVmDynamicCluster.yml @@ -0,0 +1,510 @@ +#Copyright (c) 2021 Oracle and/or its affiliates. +#Released under the Universal Permissive License v1.0 as shown at +# https://oss.oracle.com/licenses/upl/ + +name: Test Dynamic Cluster on VM +run-name: Test Dynamic Cluster on VM with `db`:${{ inputs.databaseType }} + +on: + workflow_dispatch: + inputs: + location: + description: 'Location of the resources' + required: true + default: 'centralus' + databaseType: + description: 'Database connection' + required: true + default: 'mssqlserver' + type: choice + options: + - mssqlserver + - mssqlserver-passwordless + - postgresql(flexible) + - postgresql-passwordless(flexible) + # Allows you to run this workflow using GitHub APIs + # PERSONAL_ACCESS_TOKEN= + # REPO_NAME=oracle/weblogic-azure/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster + # curl --verbose -XPOST -u "mriccell:${PERSONAL_ACCESS_TOKEN}" -H "Accept: application/vnd.github.everest-preview+json" -H "Content-Type: application/json" https://api.github.com/repos/${REPO_NAME}/dispatches --data '{"event_type": "test-vm-dynamic-cluster"}' + repository_dispatch: + types: [test-vm-dynamic-cluster,integration-test-all] + +env: + adminConsolePort: 7001 + adminPassword: ${{ secrets.WLS_PSW }} + dbAdminUser: weblogic + dbName: wlsdb${{ github.run_id }}${{ github.run_number }} + dbServerName: db${{ github.run_id }}${{ github.run_number }} + uamiName: uami${{ github.run_id }}${{ github.run_number }} + dynamicClusterSize: 1 + gitEmail: ${{ secrets.USER_EMAIL }} + gitToken: ${{ secrets.GIT_TOKEN }} + gitUserName: ${{ secrets.USER_NAME }} + location: centralus + nsg: wls-nsg + managedServerPrefix: managedServer + managedServers: "managedServer1" + managedServerVM: "managedServerVM1" + maxDynamicClusterSize: 2 + offerName: arm-oraclelinux-wls-dynamic-cluster + offerPath: weblogic-azure/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster + repoName: weblogic-azure + repoOwner: ${{ github.repository_owner }} + resourceGroupForDependency: wlsd-${{ github.repository_owner }}-${{ github.run_id }}-${{ github.run_number }} + resourceGroupPrefix: wls-${{ github.repository_owner }}-${{ github.run_id }}-${{ github.run_number }} + testbranchName: cicd-${{ github.run_id }}-${{ github.run_number }} + wlsDomainName: dyClusterDomain + wlsPassword: ${{ secrets.WLS_PSW }} + wlsUserName: weblogic + images: | + owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest + owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest + owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest + owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest + owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest + owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest + owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest + owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest + owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest + owls-122140-jdk8-rhel76;Oracle:weblogic-122140-jdk8-rhel76:owls-122140-jdk8-rhel76;latest + owls-141100-jdk8-rhel76;Oracle:weblogic-141100-jdk8-rhel76:owls-141100-jdk8-rhel76;latest + owls-141100-jdk11-rhel76;Oracle:weblogic-141100-jdk11-rhel76:owls-141100-jdk11-rhel76;latest + +jobs: + preflight: + outputs: + artifactName: ${{steps.artifact_file.outputs.artifactName}} + location: ${{ steps.setup-env-variables-based-on-dispatch-event.outputs.location }} + runs-on: ubuntu-latest + steps: + - name: Setup environment variables + id: setup-env-variables-based-on-dispatch-event + run: | + location=centralus # default value + + if [ ${{ github.event_name }} == 'workflow_dispatch' ]; then + location=${{ github.event.inputs.location }} + else + location=${{ github.event.client_payload.location }} + fi + + echo "##[set-output name=location;]${location}" + echo "location=${location}" >> $GITHUB_ENV + - uses: actions/checkout@v2.3.4 + - name: Set up Maven with GitHub token + uses: ./.github/actions/setupmaven + with: + token: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/checkout@v2.3.4 + - name: Set dependency reference + uses: ./.github/actions/setvars + with: + varFilePath: ./.github/variables/vm-dependencies.env + - name: Checkout arm-ttk + uses: actions/checkout@v2 + with: + repository: Azure/arm-ttk + path: arm-ttk + ref: ${{ env.refArmTtk }} + - name: Checkout ${{env.repoOwner}}/${{env.repoName}} + uses: actions/checkout@v2 + with: + repository: ${{env.repoOwner}}/${{env.repoName}} + path: ${{env.repoName}} + - name: Built and test ${{env.offerName}} + run: mvn -Ptemplate-validation-tests clean install --file ${{ env.offerPath }}/pom.xml + + - name: Checkout ${{env.repoOwner}}/${{env.repoName}} + uses: actions/checkout@v2 + with: + repository: ${{env.repoOwner}}/${{env.repoName}} + path: ${{env.repoName}}-dev + - name: Create a new branch with development pids in nestedtemplates + run: | + current=`pwd` + echo "current=${current}" >> $GITHUB_ENV + offerDevPath=${{ env.repoName }}-dev/weblogic-azure-vm/${{env.offerName}}/${{env.offerName}} + cd ${offerDevPath}/src/main/arm/nestedtemplates + git config --global core.longpaths true + git config --global user.email $gitEmail + git config --global user.name $gitUserName + echo "create branch $testbranchName" + git checkout -b $testbranchName + rm -r -f $current/${offerDevPath}/src/main/arm/nestedtemplates/* + cp -r -f $current/${{ env.offerPath }}/${{ env.offerName }}/target/arm/nestedtemplates/* $current/${offerDevPath}/src/main/arm/nestedtemplates/ + git status + git commit -a -m "hard code pids" + git push https://$gitToken@github.com/${GITHUB_REPOSITORY}.git -f + + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + - name: Validate deployment templates for different combinations of service integration + id: validate-deployment-templates + run: | + bash ${{ env.offerPath }}/test/scripts/verify-deployments.sh <<< \ + "${{ github.run_id }}${{ github.run_number }} ${location} \ + ${{ env.offerPath }}/${offerName}/target/arm/mainTemplate.json \ + ${GITHUB_REPOSITORY} ${testbranchName} ${{ env.offerPath }}/test/scripts" + + - name: Generate artifact file name and path + id: artifact_file + run: | + version=$(mvn -q -Dexec.executable=echo -Dexec.args='${version.${{ env.offerName }}}' --file weblogic-azure/pom.xml --non-recursive exec:exec) + artifactName=${{ env.offerName }}-$version-arm-assembly + unzip ${{ env.offerPath }}/${{ env.offerName }}/target/$artifactName.zip -d ${{ env.offerPath }}/${{ env.offerName }}/target/$artifactName + echo "##[set-output name=artifactName;]${artifactName}" + echo "##[set-output name=artifactPath;]${{ env.offerPath }}/${{ env.offerName }}/target/$artifactName" + - name: Archive ${{env.offerName}} template + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + if: success() + with: + name: ${{steps.artifact_file.outputs.artifactName}} + path: ${{steps.artifact_file.outputs.artifactPath}} + + deploy-dependencies: + needs: preflight + runs-on: ubuntu-latest + steps: + - name: Initialize environment variables + run: | + echo "location=${{needs.preflight.outputs.location}}" >> $GITHUB_ENV + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + - name: Create Resource Group + id: create-resource-group + run: | + echo "create resource group" ${{ env.resourceGroupForDependency }} + az group create --verbose --name ${{ env.resourceGroupForDependency }} --location ${location} + + deploy-weblogic-cluster: + needs: [preflight, deploy-dependencies] + runs-on: ubuntu-latest + steps: + - name: Initialize environment variables + run: | + echo "location=${{needs.preflight.outputs.location}}" >> $GITHUB_ENV + + - name: Checkout weblogic-azure repository + uses: actions/checkout@v4 + with: + path: ${{env.repoName}} + + - name: Download artifact for deployment + uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1 + with: + name: ${{ needs.preflight.outputs.artifactName }} + path: ${{needs.preflight.outputs.artifactName}} + + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - uses: actions/setup-java@v4 + with: + distribution: 'microsoft' + java-version: '11' + + - name: Checkout WebLogic-Cafe + uses: actions/checkout@v2 + with: + repository: azure-javaee/weblogic-on-azure + path: weblogic-on-azure + + - name: Maven build the web app + run: | + echo "build the WebLogic Cafe web app" + mvn -DskipTests clean install --file weblogic-on-azure/javaee/weblogic-cafe/pom.xml + + - name: Provision database + id: database-provision + uses: ./weblogic-azure/.github/actions/database-provision + with: + databaseType: ${{ inputs.databaseType }} + resourceGroup: ${{ env.resourceGroupForDependency }} + uamiName: ${{ env.uamiName }} + location: ${{ env.location }} + dbInstanceName: ${{ env.dbServerName }} + dbPassword: ${{ env.wlsPassword }} + databaseName: ${{ env.dbName }} + dbAdminUser: ${{ env.dbAdminUser }} + + - name: Get database parameters + id: database-parameters + uses: ./weblogic-azure/.github/actions/database-parameters + with: + databaseType: ${{ inputs.databaseType }} + uamiId: ${{ steps.database-provision.outputs.uamiId }} + serverHost: ${{ steps.database-provision.outputs.serverHost }} + dbInstanceName: ${{ env.dbServerName }} + databaseName: ${{ env.dbName }} + dbAdminUser: ${{ env.dbAdminUser }} + + - name: Try each image until one succeeds + run: | + # Convert multiline string to array + IFS=$'\n' read -d '' -r -a image_array <<< "${{ env.images }}" || true + + success=false + + for image in "${image_array[@]}"; do + if [ -z "$image" ]; then + continue + fi + + echo "::group::Trying image: $image" + + # Set deployment variables for this image + imageUrn="$image" + sku=${imageUrn%%;*} + resourceGroup=$(echo "${resourceGroupPrefix}-${sku}" | sed "s/_//g") + + echo "Deploying with SKU: $sku" + echo "Resource Group: $resourceGroup" + + # Export db variables for envsubst + export databaseType='${{ steps.database-parameters.outputs.databaseType }}' + export enableDB=${{ steps.database-parameters.outputs.enableDB }} + export enablePswlessConnection=${{ steps.database-parameters.outputs.enablePswlessConnection }} + export dsConnectionURL='${{ steps.database-parameters.outputs.dsConnectionURL }}' + export dbUser='${{ steps.database-parameters.outputs.dbUser }}' + export dbIdentity='${{ steps.database-parameters.outputs.dbIdentity }}' + export dbPassword='${{ env.wlsPassword}}' + export dbName='${{ env.dbName }}' + export dbServerName='${{ env.dbServerName }}' + + # Try deployment with this image + if bash -c " + set -e + + # Create Resource Group + echo 'Creating resource group: $resourceGroup' + az group create --verbose --name '$resourceGroup' --location '${location}' + + # Generate selfsigned certificate + echo 'Generate selfsigned certificate' + bash '${{ env.offerPath }}/test/scripts/generate-selfsigned-keystore.sh' <<< \ + '${wlsPassword} ${wlsPassword} ${wlsPassword}' + + echo 'Current working directory: $(pwd)' + # check whether identity.jks exists + if [ ! -f identity.jks ]; then + echo 'Error: identity.jks not found!' + else + echo 'identity.jks found!' + fi + + # Generate deployment parameters + echo 'Generate deployment parameters...' + export location='${{ env.location }}' + export adminPasswordOrKey='${{ env.wlsPassword }}' + export wlsdomainname='${{ env.wlsDomainName }}' + export wlsusername='${{ env.wlsUserName }}' + export wlspassword='${{ env.wlsPassword }}' + export maxDynamicClusterSize='${{ env.maxDynamicClusterSize }}' + export dynamicClusterSize='${{ env.dynamicClusterSize }}' + export skuUrnVersion='$image' + export testbranchName='${{ env.testbranchName }}' + export managedServerPrefix=${{ env.managedServerPrefix }} + export repoPath='${GITHUB_REPOSITORY}' + export uploadedKeyStoreData=\$(cat identity.jks | base64 -w 0) + + export DOLLAR='$' + echo 'Generating parameter file...' + envsubst < './${{ env.offerPath }}/test/scripts/parameters-deploy-template.json' > './${{ env.offerPath }}/test/parameters-deploy-${{ github.job }}.json' + + # Accept Image Terms + echo 'Accepting terms for image: $image' + rawUrn='$image' + publisherAndName=\$(echo \${rawUrn} | grep -o ';.*:' | sed 's/;//g') + imageVersion=\${rawUrn##*;} + az vm image terms accept --urn \${publisherAndName}$sku:\${imageVersion} + + # Deploy WebLogic Server Dynamic Cluster + echo 'Deploying WebLogic Server Dynamic Cluster...' + echo 'current path is: $(pwd)' + echo 'artifactName is: ${{ needs.preflight.outputs.artifactName }}' + az deployment group create \ + --verbose \ + --resource-group '$resourceGroup' \ + --name wls-dycluster-node \ + --parameters @'${{ env.offerPath }}/test/parameters-deploy-${{ github.job }}.json' \ + --template-file '${{needs.preflight.outputs.artifactName}}/mainTemplate.json' + + # Get admin VM name + adminVMName=\$(az deployment group show \ + --resource-group '$resourceGroup' \ + --name wls-dycluster-node \ + --query 'properties.outputs.adminVMName.value' -o tsv) + + # Verify wls admin services + echo 'Verifying WebLogic admin services...' + message=\$(az vm run-command invoke \ + --resource-group '$resourceGroup' \ + --name \$adminVMName \ + --command-id RunShellScript \ + --scripts @'${{ env.offerPath }}/test/scripts/verify-admin-services.sh' \ + --query value[*].message) + + if [[ \$message == *'not in active (running) state'* ]]; then + echo 'Error: \$message' + exit 1 + fi + + # Verify wls managed server services + echo 'Verifying WebLogic managed server services...' + managedServerVMNamePrefix=\$(az deployment group show \ + --resource-group '$resourceGroup' \ + --name wls-dycluster-node \ + --query 'properties.outputs.managedServerVMNamePrefix.value' -o tsv) + + managedServer1=\"\${managedServerVMNamePrefix}1\" + message=\$(az vm run-command invoke \ + --resource-group '$resourceGroup' \ + --name \$managedServer1 \ + --command-id RunShellScript \ + --scripts @'${{ env.offerPath }}/test/scripts/verify-node-services.sh' \ + --query value[*].message) + + if [[ \$message == *'not in active (running) state'* ]]; then + echo 'Error: \$message' + exit 1 + fi + + # Get public IP + publicIP=\$(az vm show \ + --resource-group '$resourceGroup' \ + --name \$adminVMName -d \ + --query publicIps -o tsv) + + # Verify WebLogic Server Access + echo 'Verifying WebLogic Server Access...' + bash '${{ env.offerPath }}/test/scripts/verify-wls-access.sh' <<< \"\$publicIP ${adminConsolePort} $wlsUserName $wlsPassword $managedServers\" + + # Verify WebLogic Managed Server LifeCycle + echo 'Verifying WebLogic managed server lifecycle...' + bash '${{ env.offerPath }}/test/scripts/verify-servers-lifecycle.sh' <<< \"$wlsUserName $wlsPassword \$publicIP ${adminConsolePort} $managedServers\" + + # Query admin VM DNS + echo 'Querying admin VM DNS...' + adminNicId=\$(az vm show \ + --resource-group '$resourceGroup' \ + --name \$adminVMName \ + --query networkProfile.networkInterfaces[0].id -o tsv) + adminPublicIPId=\$(az network nic show --id \${adminNicId} --query ipConfigurations[0].publicIPAddress.id -o tsv) + adminVMDNS=\$(az network public-ip show \ + --id \"\${adminPublicIPId}\" \ + --query dnsSettings.fqdn -o tsv) + + # Deploy WebLogicCafe app + echo 'Deploying WebLogicCafe app...' + timeout 6m sh -c 'until nc -zv \$0 \$1; do echo \"nc rc: \$?\"; sleep 5; done' \${adminVMDNS} ${adminConsolePort} + bash '${{ env.offerPath }}/test/scripts/deploy-webapp.sh' <<< \"$wlsUserName $wlsPassword \${adminVMDNS} ${adminConsolePort}\" + + # Query OHS Access URL + echo 'Querying OHS Access URL...' + ohsAccessURL=\$(az deployment group show \ + --resource-group '$resourceGroup' \ + --name wls-dycluster-node \ + --query 'properties.outputs.ohsAccessURL.value' -o tsv) + + # Verify WebLogicCafe app deployment + echo 'Verifying WebLogicCafe app deployment...' + bash '${{ env.offerPath }}/test/scripts/verify-webapp-deployment.sh' <<< \"\${ohsAccessURL}\" + + echo 'SUCCESS: All verification steps passed!' + exit 0 + "; then + echo "✅ SUCCESS: WebLogic deployment succeeded with image: $image" + echo "successful_image=$image" >> $GITHUB_ENV + echo "successful_resource_group=$resourceGroup" >> $GITHUB_ENV + success=true + + # Clean up successful deployment + echo "Cleaning up resource group: $resourceGroup" + az group delete --yes --no-wait --verbose --name "$resourceGroup" || true + + break + else + echo "❌ FAILED: WebLogic deployment failed with image: $image, trying next..." + # Clean up failed deployment + echo "Cleaning up failed resource group: $resourceGroup" + # az group delete --yes --no-wait --verbose --name "$resourceGroup" || true + fi + echo "::endgroup::" + done + + if [ "$success" = "false" ]; then + echo "💥 All images failed!" + exit 1 + else + echo "🎉 Workflow succeeded with image: ${{ env.successful_image }}" + fi + + + cleanup-github-resource: + needs: deploy-weblogic-cluster + if: always() + runs-on: ubuntu-latest + steps: + - name: Checkout ${{env.repoName}} + uses: actions/checkout@v2 + with: + repository: ${{ env.repoOwner }}/${{env.repoName}} + path: ${{env.repoName}} + - name: Delete testing branch + run: | + cd ${{env.repoName}} + git push https://$gitToken@github.com/${GITHUB_REPOSITORY}.git -f --delete $testbranchName + + cleanup-az-resource: + if: always() + needs: deploy-weblogic-cluster + runs-on: ubuntu-latest + steps: + - uses: azure/login@v1 + id: azure-login + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + - name: Delete DB Resource Group + id: delete-db-resource-group + run: | + echo "delete... " $resourceGroup + az group delete --yes --no-wait --verbose --name ${{ env.resourceGroupForDependency }} + - name: Delete Resource Group + id: delete-resource-group + run: | + echo "delete resource group with prefix:" ${{ env.resourceGroupPrefix }} + az group list --query "[?starts_with(name, '${{ env.resourceGroupPrefix }}')].[name]" -o tsv | xargs -I {} az group delete --name {} --yes --no-wait + + summary: + needs: deploy-weblogic-cluster + if: always() + runs-on: ubuntu-latest + steps: + - name: summarize jobs + if: ${{ github.repository_owner == 'wls-eng' }} + run: | + workflow_jobs=$(curl -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/${GITHUB_REPOSITORY}/actions/runs/${{ github.run_id }}/jobs) + critical_job_num=$(echo $workflow_jobs | jq '.jobs | map(select(.name|test("^deploy-weblogic-cluster."))) | length') + echo "$critical_job_num" + succeed_critical_job_num=$(echo $workflow_jobs | jq '.jobs | map(select(.conclusion=="success") | select(.name|test("^deploy-weblogic-cluster."))) | length') + echo "$succeed_critical_job_num" + failed_job_num="$(($critical_job_num-$succeed_critical_job_num))" + echo $failed_job_num + if (($failed_job_num >= 2));then + echo "too many jobs failed, send notification to Teams" + curl ${{ secrets.MSTEAMS_WEBHOOK }} \ + -H 'Content-Type: application/json' \ + --data-binary @- << EOF + { + "@context":"http://schema.org/extensions", + "@type":"MessageCard", + "text":"$failed_job_num jobs failed in Dynamic Cluster Offer's workflow, please take a look at: https://github.com/${GITHUB_REPOSITORY}/actions/runs/${{ github.run_id }}" + } + EOF + fi diff --git a/README.md b/README.md index 3d6d7fcf9..f78551fdc 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,249 @@ As part of a broad-ranging partnership between Oracle and Microsoft, this project offers support for running Oracle WebLogic Server in the Azure Virtual Machines and Azure Kubernetes Service (AKS). The partnership includes joint support for a range of Oracle software running on Azure, including Oracle WebLogic, Oracle Linux, and Oracle DB, as well as interoperability between Oracle Cloud Infrastructure (OCI) and Azure. +## Integration tests report +* [![CI Validation for Build](https://github.com/oracle/weblogic-azure/actions/workflows/it-validation-build.yaml/badge.svg)](https://github.com/oracle/weblogic-azure/actions/workflows/it-validation-build.yaml) +* [![CI Validation for AKS](https://github.com/oracle/weblogic-azure/actions/workflows/it-validation-aks.yaml/badge.svg)](https://github.com/oracle/weblogic-azure/actions/workflows/it-validation-aks.yaml) +* [![CI Validation for VM Admin](https://github.com/oracle/weblogic-azure/actions/workflows/it-validation-vm-admin.yaml/badge.svg)](https://github.com/oracle/weblogic-azure/actions/workflows/it-validation-vm-admin.yaml) +* [![CI Validation for VM Cluster](https://github.com/oracle/weblogic-azure/actions/workflows/it-validation-vm-cluster.yaml/badge.svg)](https://github.com/oracle/weblogic-azure/actions/workflows/it-validation-vm-cluster.yaml) +* [![CI Validation for VM Dynamic Cluster](https://github.com/oracle/weblogic-azure/actions/workflows/it-validation-vm-dynamic-cluster.yaml/badge.svg)](https://github.com/oracle/weblogic-azure/actions/workflows/it-validation-vm-dynamic-cluster.yaml) + ## Installation The [Azure Marketplace WebLogic Server Offering](https://azuremarketplace.microsoft.com/en-us/marketplace/apps?search=WebLogic) offers a simplified UI and installation experience over the full power of the Azure Resource Manager (ARM) template. ## Documentation -Please refer to the README for [documentation on WebLogic Server running on an Azure Kubernetes Service](https://github.com/oracle/weblogic-azure/weblogic-azure-aks/README.md) +Please refer to the README for [documentation on WebLogic Server running on an Azure Kubernetes Service](https://oracle.github.io/weblogic-kubernetes-operator/userguide/aks/) Please refer to the README for [documentation on WebLogic Server running on an Azure Virtual Machine](https://docs.oracle.com/en/middleware/standalone/weblogic-server/wlazu/get-started-oracle-weblogic-server-microsoft-azure-iaas.html#GUID-E0B24A45-F496-4509-858E-103F5EBF67A7) +## Local Build Setup and Requirements + +This project utilizes [GitHub Packages](https://github.com/features/packages) for hosting and retrieving some dependencies. To ensure you can smoothly run and build the project in your local environment, specific configuration settings are required. + +GitHub Packages requires authentication to download or publish packages. Therefore, you need to configure your Maven `settings.xml` file to authenticate using your GitHub credentials. The primary reason for this is that GitHub Packages does not support anonymous access, even for public packages. + +Please follow these steps: + +1. Create a Personal Access Token (PAT) + - Go to [Personal access tokens](https://github.com/settings/tokens). + - Click on Generate new token. + - Give your token a descriptive name, set the expiration as needed, and select the scopes (read:packages, write:packages). + - Click Generate token and make sure to copy the token. + +2. Configure Maven Settings + - Locate or create the settings.xml file in your .m2 directory(~/.m2/settings.xml). + - Add the GitHub Package Registry server configuration with your username and the PAT you just created. It should look something like this: + ```xml + + + + + + + github + YOUR_GITHUB_USERNAME + YOUR_PERSONAL_ACCESS_TOKEN + + + + + + + ``` + + +## Deployment Description + +### WLS on VMs + +#### Oracle WebLogic Server Single Node + +The offer provisions the following Azure resources based on Oracle WebLogic Server base images and an Oracle WebLogic Server Enterprise Edition (WLS) without domain configuration. + +- The offer includes a choice of operating system, JDK, Oracle WebLogic Server versions. + - OS: Oracle Linux or Red Hat Enterprise Linux + - JDK: Oracle JDK 8, or 11 + - WLS version: 12.2.1.4, 14.1.1.0 +- Computing resources + - A VM with the following configurations: + - Operating system as described in the selected base image. + - Choice of VM size. + - An OS disk attached to the VM. +- Network resources + - A virtual network and a subnet. + - A network security group. + - A network interface. + - A public IP address assigned to the network interface. +- Storage resources + - An Azure Storage Account to store the VM diagnostics profile. +- Key Software components + - Oracle WebLogic Server Enterprise Edition. Version as described in the selected base image. The **ORACLE_HOME** is **/u01/app/wls/install/oracle/middleware/oracle_home**. + - Oracle JDK. The version as described in the selected base image. The **JAVA_HOME** is **/u01/app/jdk/jdk-${version}**. + - In addition to the database drivers that come standard with WLS, the offer includes the most recent supported PostgreSQL JDBC driver and Microsoft SQL JDBC driver. The drivers are stored in **/u01/app/wls/install/oracle/middleware/oracle_home/wlserver/server/lib/**. + +#### Oracle WebLogic Server with Admin Server + +The offer provisions Oracle WebLogic Server (WLS) with a domain and Administration Server. All supporting Azure resources are automatically provisioned. + +- The offer includes a choice of operating system, JDK, Oracle WLS versions. + - OS: Oracle Linux or Red Hat Enterprise Linux + - JDK: Oracle JDK 8, or 11 + - WLS version: 12.2.1.4, 14.1.1.0 +- Computing resources + - VM with the followings configuration: + - A VM to run the Administration Server. + - Choice of VM size. + - An OS disk attached to the VM. +- Network resources + - A virtual network and a subnet. If desired, you can deploy into a pre-existing virtual network. + - A network security group if creating a new virtual network. + - Network interface for VM. + - Public IP address. +- Key software components + - Oracle WLS Enterprise Edition. Version as described in the selected base image. The **ORACLE_HOME** is **/u01/app/wls/install/oracle/middleware/oracle_home**. + - Oracle JDK. The version as described in the selected base image. The **JAVA_HOME** is **/u01/app/jdk/jdk-${version}**. + - A WLS domain with the Administration Server up and running. Admin server sign in with the user name and password provided to the offer. The default domain name is **adminDomain**, the domain path is **/u01/domains/adminDomain/**. +- Database connectivity + - The offer provides database connectivity for PostgreSQL, Oracle database, Azure SQL, MySQL, or an arbitrary JDBC compliant database. + - Some database options support Azure Passwordless database connection. +- Access URLs + - See the deployment outputs for access URLs. + +#### Oracle WebLogic Server Cluster + +The offer provisions Oracle WebLogic Server (WLS) Enterprise Edition with a domain, the Administration Server and a configured cluster. All supporting Azure resources are automatically provisioned. + +- The offer includes a choice of operating system, JDK, WLS versions. + - OS: Oracle Linux or Red Hat Enterprise Linux + - JDK: Oracle JDK 8, or 11 + - WLS version: 12.2.1.4, 14.1.1.0 +- Computing resources + - VMs with the followings configurations: + - A VM to run the Administration Server and VMs to run Managed Servers. + - VMs to run Coherence Cache servers. + - Choice of VM size. + - An OS disk attached to the VM. +- Load Balancer + - If desired, an Azure Application Gateway (agw). The TLS/SSL certificate for the agw can be uploaded, retrieved from a key vault, or self-signed auto-generated. +- Network resources + - A virtual network and a subnet. If desired, you can deploy into a pre-existing virtual network. + - A network security group if creating a new virtual network. + - Network interfaces for VMs. + - Public IP addresses assigned to the network interfaces + - Public IP assigned for agw, if desired. +- High Availability + - An Azure Availability Set for the VMs. +- Key software components + - WLS Enterprise Edition. Version as described in the selected base image. The **ORACLE_HOME** is **/u01/app/wls/install/oracle/middleware/oracle_home**. + - Oracle JDK. The version as described in the selected base image. The **JAVA_HOME** is **/u01/app/jdk/jdk-${version}***. + - A WLS domain with the Administration Server up and running. Admin server sign in with the user name and password provided to the offer. The default domain name is **wlsd**, the domain path is **/u01/domains/wlsd/**. + - A configured cluster with Managed Servers running. The number of managed servers is specified in the UI when deploying the offer. + - Coherence Cache. If you select to enable Coherence Cache, the offer creates a data tier configured with Managed Coherence cache servers. +- Database connectivity + - The offer provides database connectivity for PostgreSQL, Oracle database, Azure SQL, MySQL, or an arbitrary JDBC compliant database. + - Some database options support Azure Passwordless database connection. +- Access URLs + - See the deployment outputs for access URLs. + +#### Oracle WebLogic Server Dynamic Cluster + +The offer provisions Oracle WebLogic Server (WLS) Enterprise Edition with a domain, the Administration Server and a dynamic cluster. All supporting Azure resources are automatically provisioned. + +- The offer includes a choice of operating system, JDK, WLS versions. + - OS: Oracle Linux or Red Hat Enterprise Linux + - JDK: Oracle JDK 8, or 11 + - WLS version: 12.2.1.4, 14.1.1.0 +- The offer includes the choice of the following Oracle HTTP Server (OHS) base images + - OS: Oracle Linux + - OHS version 12.2.1.4.0 +- Computing resources + - VMs for WLS: + - A VM to run the Administration Server and VMs to run Managed Servers. + - VMs to run Coherence Cache servers. + - Choice of VM size. + - An OS disk attached to the VM. + - VM for OHS, if desired: + - Choice of VM size. + - An OS disk attached to the VM. +- Load Balancer + - If desired, an OHS. The TLS/SSL certificate for the OHS can be uploaded, or retrieved from a key vault. +- Network resources + - A virtual network and a subnet. If desired, you can deploy into a pre-existing virtual network. + - A network security group if creating a new virtual network. + - Network interfaces for VMs. + - Public IP addresses assigned to the network interfaces. + - A public IP assigned OHS, if desired. +- Storage resources + - An Azure Storage Account and a file share named **wlsshare**. The mount point is **/mnt/wlsshare**. + - The storage account is also used to store the diagnostics profile of the VMs. + - A private endpoint in the same subnet with the VM, which allows the VM to access the file share. +- Key software components for WLS + - WLS Enterprise Edition. Version as described in the selected base image. The **ORACLE_HOME** is **/u01/app/wls/install/oracle/middleware/oracle_home**. + - Oracle JDK. The version as described in the selected base image. The **JAVA_HOME** is **/u01/app/jdk/jdk-${version}**. + - A WLS domain with the Administration Server up and running. Admin server sign in with the user name and password provided to the offer. The default domain name is **wlsd**, the domain path is **/u01/domains/wlsd/**. + - A dynamic cluster with desired number of Managed Servers running. The number of Managed servers is specified by **Initial Dynamic Cluster Size**. The cluster size is specified by **Maximum Dynamic Cluster Size**. + - Coherence Cache. If you select to enable Coherence Cache, the offer creates a data tier configured with Managed Coherence cache servers. +- Key software components for OHS + - Version as described in the selected base image. The **ORACLE_HOME** is **/u01/app/ohs/install/oracle/middleware/oracle_home**. + - Oracle JDK. The version as described in the selected base image. The **JAVA_HOME** is **/u01/app/jdk/jdk-${version}**. + - A domain is configured based on the node manager user name and credentials provided by the user. The default domain name is **ohsStandaloneDomain**, the domain path is **/u01/domains/ohsStandaloneDomain/**. + - An Oracle HTTP Server Component with default name **ohs_component**. +- Database connectivity + - The offer provides database connectivity for PostgreSQL, Oracle database, Azure SQL, MySQL, or an arbitrary JDBC compliant database. + - Some database options support Azure Passwordless database connection. +- Access URLs + - See the deployment outputs for access URLs. + +### WLS on AKS + +The offer provisions an Oracle WebLogic Server Enterprise Edition (WLS) and supporting Azure resources. WLS is configured with a domain, the Administration Server and a dynamic cluster set up and running. + +- The offer includes the choice of the following WLS container images + - Images from Oracle Container Registry (OCR) (General or Patched images) + - OS: Oracle Linux or Red Hat Enterprise Linux + - JDK: Oracle JDK 8, or 11 + - WLS version: 12.2.1.4, 14.1.1.0 + - You can specify any arbitrary docker image tag that is available from OCR. + - An image from your own Azure Container Registry. +- Computing resources + - Azure Kubernetes Service cluster + - Dynamically created AKS cluster with + - Choice of Node count. + - Choice of Node size. + - Network plugin: Azure CNI. + - If desired, you can also deploy into a pre-existing AKS cluster. + - An Azure Container Registry. If desired, you can select a pre-existing Azure Container Registry. +- Network resources + - A virtual network and a subnet. If desired, you can deploy into a pre-existing virtual network. + - Public IP addresses assigned to the managed load balancer and Azure Application Gateway, if selected. +- Load Balancer + - Choice of Azure Application Gateway (agw) or standard load balancer service. With agw, you can upload TLS/SSL certificate, use a certificates stored in a key vault, or allow a self-signed certificate to be generated and installed. +- Storage resources + - An Azure Storage Account and a file share named weblogic if you select to create Persistent Volume using Azure File share service. The mount point is **/shared**. +- Monitoring resources + - If desired, Azure Container Insights and workspace. +- Key software components + - Oracle WebLogic Server Enterprise Edition. The **ORACLE_HOME** is **/u01/app/wls/install/oracle/middleware/oracle_home**. + - This offer always deploys WLS using the 'Model in image' domain home source type. For more information, see the documentation from Oracle. + - WebLogic Kubernetes Operator + - Oracle JDK. The **JAVA_HOME** is **/u01/app/jdk/jdk-${version}**. + - A WLS domain with the Administration Server up configured based on the provided Administrator user name and credentials. The default domain name is sample-domain1, the domain path is **/u01/domains/sample-domain1/**. + - A dynamic cluster with Managed Servers running. The number of initial and maximum number of Managed Servers are configurable. +- Database connectivity + - The offer provides database connectivity for PostgreSQL, Oracle database, Azure SQL, MySQL, or an arbitrary JDBC compliant database. + - Some database options support Azure Passwordless database connection. +- Access URLs + - See the deployment outputs for access URLs. + ## Examples To get details of how to run Oracle WebLogic Server on Azure Virtual Machines refer to the blog [WebLogic on Azure Virtual Machines Major Release Now Available](https://blogs.oracle.com/weblogicserver/weblogic-on-azure-virtual-machines-major-release-now-available). diff --git a/SECURITY.md b/SECURITY.md index 3c4ad917a..2ca81027f 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -21,9 +21,7 @@ security features are welcome on GitHub Issues. Security updates will be released on a regular cadence. Many of our projects will typically release security fixes in conjunction with the -[Oracle Critical Patch Update][3] program. Security updates are released on the -Tuesday closest to the 17th day of January, April, July and October. A pre-release -announcement will be published on the Thursday preceding each release. Additional +Oracle Critical Patch Update program. Additional information, including past advisories, is available on our [security alerts][4] page. diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..2b3b164cc --- /dev/null +++ b/pom.xml @@ -0,0 +1,97 @@ + + + + + 4.0.0 + + + com.microsoft.azure.iaas + azure-javaee-iaas-parent + 1.0.22 + + + com.oracle.weblogic.azure + weblogic-azure + pom + 1.0.0 + ${project.artifactId} + https://github.com/oracle/weblogic-azure + + + + github + GitHub Packages + https://maven.pkg.github.com/azure-javaee/azure-javaee-iaas + + + + + + github + GitHub Packages + https://maven.pkg.github.com/azure-javaee/azure-javaee-iaas + + + + + + + 1.0.93 + + 1.0.32 + 1.0.58 + 1.0.740000 + 1.0.55 + + 1.0.7 + 1.0.3 + 1.0.3 + + 1.0.28 + 1.0.3 + 1.0.3 + + + + main + + weblogic-azure + + oracle + + https://raw.githubusercontent.com/${git.repo.owner}/${git.repo}/${git.tag}/weblogic-azure-vm + + ${project.basedir} + + ${module.basedir}/../arm-ttk/arm-ttk + + file:///${module.basedir}/resources/azure-common.properties + file:///${module.basedir}/resources/pid.properties + file:///${module.basedir}/resources/microsoft-pid.properties + + + + + true + + true + + true + + + + + + weblogic-azure-aks + weblogic-azure-vm + + + diff --git a/resources/azure-common.properties b/resources/azure-common.properties new file mode 100644 index 000000000..7eb83b106 --- /dev/null +++ b/resources/azure-common.properties @@ -0,0 +1,85 @@ +## Use the following command to get the latest 10 API versions for a given resource type +## ```bash +## export NameSpace= +## export ResourceType= +## az provider show --namespace ${NameSpace} --query "resourceTypes[?resourceType=='${ResourceType}'].apiVersions[:10]" \ +## | jq -r '.[][] | select(test("preview$"; "i") | not)' | head -n 10 +## ``` +## + +# Microsoft.Authorization/roleAssignments +azure.apiVersionForRoleAssignment=2022-04-01 +# Microsoft.Authorization/roleDefinitions +azure.apiVersionForRoleDefinitions=2022-04-01 +# Microsoft.ContainerRegistry/registries +azure.apiVersionForContainerRegistries=2023-07-01 +# Microsoft.ContainerService/managedClusters +azure.apiVersionForManagedClusters=2023-10-01 +# Microsoft.Compute/availabilitySets +azure.apiVersionForAvailabilitySets=2024-11-01 +# Microsoft.Compute/virtualMachines +azure.apiVersionForVirtualMachines=2024-11-01 +# Microsoft.KeyVault/vaults +azure.apiVersionForKeyVault=2024-11-01 +# Microsoft.KeyVault/vaults/secrets +azure.apiVersionForKeyVaultSecrets=2024-11-01 +# Microsoft.ManagedIdentity/userAssignedIdentities +azure.apiVersionForIdentity=2023-01-31 +# Microsoft.Network/networkInterfaces +azure.apiVersionForNetworkInterfaces=2023-06-01 +# Microsoft.Network/networkSecurityGroups +azure.apiVersionForNetworkSecurityGroups=2023-06-01 +# Microsoft.Network/privateEndpoints +azure.apiVersionForPrivateEndpoint=2023-06-01 +# Microsoft.Network/publicIPAddresses +azure.apiVersionForPublicIPAddresses=2023-06-01 +# Microsoft.Network/applicationGateways +azure.apiVersionForApplicationGateways=2023-06-01 +# Microsoft.Network/dnszones +azure.apiVersionForDNSZone=2023-07-01-preview +# Microsoft.Network/virtualNetworks +azure.apiVersionForVirtualNetworks=2023-06-01 +# Microsoft.OperationalInsights/workspaces +azure.apiVersionForInsightsWorkspaces=2022-10-01 +# Microsoft.Resources/deploymentScripts +azure.apiVersionForDeploymentScript=2023-08-01 +# Microsoft.Resources/deployments +azure.apiVersionForDeployment=2023-07-01 +# Microsoft.Resources/tags +azure.apiVersionForTags=2023-07-01 +# Microsoft.Storage/storageAccounts +azure.apiVersionForStorage=2025-01-01 +# Microsoft.Storage/storageAccounts/fileServices +azure.apiVersionForStorageFileService=2025-01-01 +# Microsoft.Monitor/accounts +azure.apiVersionForMonitorAccount=2023-04-03 + +# AzureAzCLI version +azure.cli.version=2.53.0 +# AzurePowerShell version +azure.powershell.version=11.5 + +# These filters are used to implement tags for resources. Other occurrences of these resource type identifiers +# are intentionally not filtered because doing so would unnecessarily complicate the code. +identifier.accounts=Microsoft.Monitor/accounts +identifier.applicationGateways=Microsoft.Network/applicationGateways +identifier.availabilitySets=Microsoft.Compute/availabilitySets +identifier.dnszones=Microsoft.Network/dnszones +identifier.managedClusters=Microsoft.ContainerService/managedClusters +identifier.networkInterfaces=Microsoft.Network/networkInterfaces +identifier.networkSecurityGroups=Microsoft.Network/networkSecurityGroups +identifier.publicIPAddresses=Microsoft.Network/publicIPAddresses +identifier.privateEndpoints=Microsoft.Network/privateEndpoints +identifier.registries=Microsoft.ContainerRegistry/registries +identifier.storageAccounts=Microsoft.Storage/storageAccounts +identifier.vaults=Microsoft.KeyVault/vaults +identifier.virtualNetworks=Microsoft.Network/virtualNetworks +identifier.virtualMachines=Microsoft.Compute/virtualMachines +identifier.virtualMachinesExtensions=Virtual machine extension +identifier.workspaces=Microsoft.OperationalInsights/workspaces +identifier.deploymentScripts=Microsoft.Resources/deploymentScripts +identifier.userAssignedIdentities=Microsoft.ManagedIdentity/userAssignedIdentities +identifier.resourcesDeployment=Microsoft resources deployment +label.tagsLabel=Tags for the resources. + +azure.armBased.vmSize.list="Standard_D2plds_v5","Standard_D4plds_v5","Standard_D8plds_v5","Standard_D16plds_v5","Standard_D32plds_v5","Standard_D48plds_v5","Standard_D64plds_v5","Standard_D2pls_v5","Standard_D4pls_v5","Standard_D8pls_v5","Standard_D16pls_v5","Standard_D32pls_v5","Standard_D48pls_v5","Standard_D64pls_v5","Standard_D2pds_v5","Standard_D4pds_v5","Standard_D8pds_v5","Standard_D16pds_v5","Standard_D32pds_v5","Standard_D48pds_v5","Standard_D64pds_v5","Standard_D2ps_v5","Standard_D4ps_v5","Standard_D8ps_v5","Standard_D16ps_v5","Standard_D32ps_v5","Standard_D48ps_v5","Standard_D64ps_v5","Standard_E2pds_v5","Standard_E4pds_v5","Standard_E8pds_v5","Standard_E16pds_v5","Standard_E20pds_v5","Standard_E32pds_v5","Standard_E2ps_v5","Standard_E4ps_v5","Standard_E8ps_v5","Standard_E16ps_v5","Standard_E20ps_v5","Standard_E32ps_v5","Standard_B2pls_v2","Standard_B2ps_v2","Standard_B2pts_v2","Standard_B4pls_v2","Standard_B4ps_v2","Standard_B8pls_v2","Standard_B8ps_v2","Standard_B16pls_v2","Standard_B16ps_v2","Standard_D2pls_v6","Standard_D4pls_v6","Standard_D8pls_v6","Standard_D16pls_v6","Standard_D32pls_v6","Standard_D48pls_v6","Standard_D64pls_v6","Standard_D96pls_v6","Standard_D2pds_v6","Standard_D4pds_v6","Standard_D8pds_v6","Standard_D16pds_v6","Standard_D32pds_v6","Standard_D48pds_v6","Standard_D64pds_v6","Standard_D96pds_v6","Standard_D2plds_v6","Standard_D4plds_v6","Standard_D8plds_v6","Standard_D16plds_v6","Standard_D32plds_v6","Standard_D48plds_v6","Standard_D64plds_v6","Standard_D96plds_v6","Standard_D2ps_v6","Standard_D4ps_v6","Standard_D8ps_v6","Standard_D16ps_v6","Standard_D32ps_v6","Standard_D48ps_v6","Standard_D64ps_v6","Standard_D96ps_v6","Standard_E2ps_v6","Standard_E4ps_v6","Standard_E8ps_v6","Standard_E16ps_v6","Standard_E32ps_v6","Standard_E48ps_v6","Standard_E64ps_v6","Standard_E96ps_v6","Standard_E2pds_v6","Standard_E4pds_v6","Standard_E8pds_v6","Standard_E16pds_v6","Standard_E32pds_v6","Standard_E48pds_v6","Standard_E64pds_v6","Standard_E96pds_v6" diff --git a/resources/doc/guidance-for-tagging-resource.md b/resources/doc/guidance-for-tagging-resource.md new file mode 100644 index 000000000..ab2ec4c1c --- /dev/null +++ b/resources/doc/guidance-for-tagging-resource.md @@ -0,0 +1,201 @@ + +# Guidance on Applying Tags in Solution Templates + +## What are Tags in this context and why are they useful? + +Tags are arbitrary name=value pairs that can be associated with most Azure resources. Azure features such as Azure Policy can use Tags to enforce cloud governance policies. For more about tags, see [Use tags to organize your Azure resources and management hierarchy](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/tag-resources). + +## Step 1: Audit Resources Created in the Offer + +To determine the resources that will be created in your offer, use the following commands based on the template type: + +### For ARM Templates: +Use the command below to list resource types: + +```bash +# Navigate to the offer folder +cd offer-folder +grep -rh "\"type\": \"Microsoft" --exclude="createUiDefinition.json" | sort | uniq | sed 's/^[ \t]*//' +``` + +### For Bicep Templates: +Use the command below to list resource types and remove duplicates: + +```bash +# Navigate to the offer folder +cd offer-folder +grep -rh "^resource" | grep "Microsoft." | sort | uniq | sed 's/^[ \t]*//' +``` + +Identify which resources support tags and which do not. For resources not listed below, consult the ARM definition at [Azure Resource Manager templates](https://learn.microsoft.com/en-us/azure/templates/) to determine if tagging is supported. If the definition does not include a tags property, the resource does not support tags and tagging is not required for deployments. + +### Resources that Support Tags: + +The top-level resources will be listed in the Tag UI control. Sub-resources will inherit the same tags as their parent resources. + +For example, in the UI definition, customers can specify tags for `Microsoft.KeyVault/vaults`, but not for `Microsoft.KeyVault/vaults/secrets`. For the deployment of `Microsoft.KeyVault/vaults/secrets`, the same tags applied to `Microsoft.KeyVault/vaults` will be used. This approach ensures a consistent tagging experience with Key Vault deployments in the Azure portal. + +- Microsoft.Network/dnszones +- Microsoft.Network/networkInterfaces +- Microsoft.Network/networkSecurityGroups +- Microsoft.Network/publicIPAddresses +- Microsoft.Network/privateEndpoints +- Microsoft.Storage/storageAccounts +- Microsoft.KeyVault/vaults + - Microsoft.KeyVault/vaults/secrets +- Microsoft.Network/virtualNetworks +- Microsoft.Compute/virtualMachines +- Microsoft.Compute/virtualMachines/extensions +- Microsoft.Resources/deploymentScripts +- Microsoft.ManagedIdentity/userAssignedIdentities +- Microsoft.Resources/deployments +- Microsoft.Network/applicationGateways + +### Resources that Do Not Support Tags: + +- Microsoft.Storage/storageAccounts/fileServices +- Microsoft.Storage/storageAccounts/fileServices/shares +- Microsoft.Network/networkSecurityGroups/securityRules +- Microsoft.Network/dnsZones/A +- Microsoft.Network/dnszones/CNAME +- Microsoft.Network/virtualNetworks/subnets +- Microsoft.Authorization/roleAssignments +- Microsoft.Network/loadBalancers/backendAddressPools +- Microsoft.Network/applicationGateways/backendHttpSettingsCollection +- Microsoft.Network/applicationGateways/frontendIPConfigurations +- Microsoft.Network/applicationGateways/frontendPorts +- Microsoft.Network/applicationGateways/gatewayIPConfigurations +- Microsoft.Network/applicationGateways/httpListeners +- Microsoft.Network/applicationGateways/probes +- Microsoft.Network/applicationGateways/requestRoutingRules + +## Step 2: Tag UI Control + +Incorporate the [Microsoft.Common.TagsByResource UI element](https://learn.microsoft.com/en-us/azure/azure-resource-manager/managed-applications/microsoft-common-tagsbyresource?WT.mc_id=Portal-Microsoft_Azure_CreateUIDef0) to include resources that support tags. + +## Step 3: Update the Template + +Refer to this [pull request](https://github.com/oracle/weblogic-azure/pull/327/) as a guide for how to apply tags to the resource deployments. + +Notes: + +For AKS, make sure the tag is applied to agent pool and node pool. The whole structure looks like: + +```bicep +resource symbolicname 'Microsoft.ContainerService/managedClusters@2024-06-02-preview' = { + name: 'string' + location: 'string' + tags: { + tagName1: 'tagValue1' + tagName2: 'tagValue2' + } + + ... + + agentPoolProfiles: { + + ... + + tags: { + tagName1: 'tagValue1' + tagName2: 'tagValue2' + } + } +} + +``` + +See [Microsoft.ContainerService managedClusters - Bicep](https://learn.microsoft.com/en-us/azure/templates/microsoft.containerservice/managedclusters?pivots=deployment-language-bicep) for more information. + +## Step 4: Testing + +1. **Create a Test Offer:** Set up a test offer to validate the tagging process. + +2. **Tag Settings:** + - Apply a uniform tag to all resources. + - Create specific tags for each resource, setting the tag value to the resource type (e.g., "tag1=storage account"). + +3. **Deploy the Offer:** + +4. **Verify Tags:** Use the following command to verify that the resources have the correct tags applied: + + ```bash + az resource list --resource-group --query "[].{Name:name, Type:type, Tags:tags}" -o json + ``` + + For example: + + ```shell + az resource list --resource-group haiche-sn-tag-test --query "[].{Name:name, Type:type, Tags:tags}" -o json + [ + { + "Name": "0733ecolvm", + "Tags": { + "Tag0": "All", + "Tag6": "storage account" + }, + "Type": "Microsoft.Storage/storageAccounts" + }, + { + "Name": "olvm_PublicIP", + "Tags": { + "Tag0": "All", + "Tag4": "public ip address" + }, + "Type": "Microsoft.Network/publicIPAddresses" + }, + { + "Name": "wls-nsg", + "Tags": { + "Tag0": "All", + "Tag3": "network security group" + }, + "Type": "Microsoft.Network/networkSecurityGroups" + }, + { + "Name": "olvm_VNET", + "Tags": { + "Tag0": "All", + "Tag8": "virtual network" + }, + "Type": "Microsoft.Network/virtualNetworks" + }, + { + "Name": "olvm_NIC", + "Tags": { + "Tag0": "All", + "Tag2": "network interface" + }, + "Type": "Microsoft.Network/networkInterfaces" + }, + { + "Name": "WeblogicServerVM", + "Tags": { + "Tag0": "All", + "Tag7": "virtual machine" + }, + "Type": "Microsoft.Compute/virtualMachines" + }, + { + "Name": "WeblogicServerVM_OsDisk_1_d1fed748ccaa4cac81df9179e6dff325", + "Tags": { + "Tag0": "All", + "Tag7": "virtual machine" + }, + "Type": "Microsoft.Compute/disks" + } + ] + ``` + +## Step 4: Known issues + +The tag is not applied to resources that are not deployed through our template, so we cannot apply tags to them from the template. + +Known resources: + +- Microsoft.Compute/virtualMachines/extensions + - OmsAgentForLinux + - MDE.Linux +- Microsoft.AlertsManagement/prometheusRuleGroups +- Microsoft.Insights/dataCollectionEndpoints +- Microsoft.Insights/dataCollectionRules diff --git a/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/microsoft-pid.properties b/resources/microsoft-pid.properties similarity index 61% rename from weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/microsoft-pid.properties rename to resources/microsoft-pid.properties index 1a630cb37..ab91a07a4 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/microsoft-pid.properties +++ b/resources/microsoft-pid.properties @@ -1,22 +1,15 @@ # Copyright (c) 2021, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -azure.apiVersion=2020-06-01 -azure.apiVersion2=2019-06-01 -azure.apiVersionForDeploymentScript=2020-10-01 -azure.apiVersionForDNSZone=2018-05-01 -azure.apiVersionForIndentity=2018-11-30 -azure.apiVersionForKeyVault=2019-09-01 - # Values in this file are read at build time for the other Azure Marketplace offer repositories # This file is for pids used when testing the offers in the Microsoft internal Marketplace account. -# Pids used in https://github.com/wls-eng/arm-oraclelinux-wls +# Pids used in https://github.com/oracle/weblogic-azure/tree/main/weblogic-azure-vm/arm-oraclelinux-wls end=4590f705-3e93-5945-95c3-eeb88b976091 start=7908d405-18b6-5394-988e-fb4cabdbf5e5 -# Pids used in https://github.com/wls-eng/arm-oraclelinux-wls-admin +# Pids used in https://github.com/oracle/weblogic-azure/tree/main/weblogic-azure-vm/arm-oraclelinux-wls-admin admin.aad.end=8295df19-fe6b-5745-ad24-51ef66522b24 admin.aad.start=fc7e031d-111d-5a3a-8b5a-e08602237dca @@ -28,8 +21,12 @@ admin.elk.end=1e26d5dd-cc3f-5308-a858-cf3257a486ca admin.elk.start=3dc18163-180b-56eb-adf2-501f97c88c7c admin.end=08e3f14d-2362-5c43-8269-133a0045d223 admin.start=4b4d5bab-1032-530c-88db-ac3f7caf440d +admin.ssl.end=5a18b3b0-d993-51b6-ac78-dbc87bb7ba65 +admin.ssl.start=2e7d27a3-f61f-54ee-bdfd-89f597d6d70c +admin.pswless.database.end=7ebb9b3e-3465-5116-99f9-e9e092bb6198 +admin.pswless.database.start=8b595cf2-9481-5466-be25-0d1b832f22b8 -# Pids used in https://github.com/wls-eng/arm-oraclelinux-wls-cluster +# Pids used in https://github.com/oracle/weblogic-azure/tree/main/weblogic-azure-vm/arm-oraclelinux-wls-cluster cluster.aad.end=3fa6990d-1fcb-54e3-95b2-1ccd1ec50e37 cluster.aad.start=a714884a-c4a6-5cfd-b014-97e7618b79c1 @@ -37,6 +34,7 @@ cluster.addnode.end=279e1f09-14b3-5569-8f1f-bf2185a4c96a cluster.addnode.start=4455d9f3-3a4c-54d2-99f8-f727c3f3dda2 cluster.addnode.coherence.end=157eac12-12ae-11eb-adc1-0242ac120002 cluster.addnode.coherence.start=157eacda-12ae-11eb-adc1-0242ac120002 +cluster.appgateway.custom.certificate=031f5ed3-892c-5efb-bd36-6db31717732d cluster.appgateway.end=36deb858-08fe-5c07-bc77-ba957a59a080 cluster.appgateway.start=391adcc9-6421-5bf8-8960-aec850ef7b0e cluster.appgateway.keyvault.start=512d14f0-3590-5dcb-ac53-db440d59ff3c @@ -53,7 +51,11 @@ cluster.dns.end=916943db-498f-59d7-a410-4cf37e9ed1ad cluster.dns.start=aa030ff6-c680-53de-8891-8dd16ce08aa6 cluster.elk.end=e4165284-b017-5df9-9b91-3f11dd8a72e5 cluster.elk.start=6890699c-97ad-5d76-91d3-3a3b7d64013f +cluster.ssl.end=63f1d185-d25c-55db-aa31-6d732d445f61 +cluster.ssl.start=eff0c5cb-3417-5745-a20d-cf5455fd5d39 cluster.end=55160205-2f03-52c5-ae30-507952c0c4ea +cluster.pswless.database.end=ae2f6529-815a-5d13-b6c2-91b92d267d7a +cluster.pswless.database.start=527a8646-465b-56c7-b495-6383eeb76e2e cluster.start=ca5e3350-ff62-5d92-83a3-acaaeae87c03 # Pids to indicate which database was chosen. No difference in these @@ -62,8 +64,9 @@ cluster.start=ca5e3350-ff62-5d92-83a3-acaaeae87c03 database.oracle=692b2d84-72f5-5992-a15d-0d5bcfef040d database.postgresql=935df06e-a5d5-5bf1-af66-4c1eb71dac7a database.sqlserver=3569588c-b89d-5567-84ee-a2c633c7204c +database.mysql=de95ae02-f841-4c48-a69e-4bf09c4271bb -# Pids used in https://github.com/wls-eng/arm-oraclelinux-wls-dynamic-cluster +# Pids used in https://github.com/oracle/weblogic-azure/tree/main/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster dynamic.aad.end=6449f9a2-0713-5a81-a886-dce6d8d5c137 dynamic.aad.start=6245e080-ab9b-5e42-ac14-fc38cc610a11 @@ -83,20 +86,44 @@ dynamic.elk.end=6303dcc8-4ec9-5dd8-91f9-e829e86fa330 dynamic.elk.start=cf939c33-1ebe-5dbb-95d2-fbe2d5cc6a4e dynamic.end=40a6f402-31ee-536a-a006-729105f55003 dynamic.start=07bf10d5-da4e-5113-b1c2-b8d802bda651 +dynamic.ssl.end=6714568e-9598-5cc9-8b42-3e4516c90e29 +dynamic.ssl.start=82efa164-f4e6-5dc1-93a4-51543e810225 +dynamic.pswless.database.end=b8114488-9109-5f46-a877-e86ef18d16e4 +dynamic.pswless.database.start=25b7acd8-5b7d-57c9-9c34-ad14837c39a6 # Pids to indicate which base image was chosen. No difference in these # between Oracle and Microsoft -from.owls-122130-8u131-ol74=caa3ea2b-cdec-55ee-8510-854ed10d7ebe -from.owls-122130-8u131-ol73=bf1d0f1a-cb9a-5453-bf70-42b4efe8c15e +#from.owls-122130-8u131-ol74=caa3ea2b-cdec-55ee-8510-854ed10d7ebe +#from.owls-122130-8u131-ol73=bf1d0f1a-cb9a-5453-bf70-42b4efe8c15e from.owls-122140-8u251-ol76=bde756bb-ce96-54d5-a478-04d9bd87e9db from.owls-141100-8u251-ol76=b6f00a34-1478-5a10-9a84-49c4051b57b8 from.owls-141100-11_07-ol76=afc8f9c5-8c5d-5d1b-ab4d-3116ca908bfd # Pids to indicate which latest base image was chosen. No difference in these # between Oracle and Microsoft -from.owls-122130-jdk8-ol74=caa3ea2b-cdec-55ee-8510-854ed10d7ebe -from.owls-122130-jdk8-ol73=bf1d0f1a-cb9a-5453-bf70-42b4efe8c15e +#from.owls-122130-jdk8-ol74=caa3ea2b-cdec-55ee-8510-854ed10d7ebe +#from.owls-122130-jdk8-ol73=bf1d0f1a-cb9a-5453-bf70-42b4efe8c15e from.owls-122140-jdk8-ol76=bde756bb-ce96-54d5-a478-04d9bd87e9db from.owls-141100-jdk8-ol76=b6f00a34-1478-5a10-9a84-49c4051b57b8 from.owls-141100-jdk11-ol76=afc8f9c5-8c5d-5d1b-ab4d-3116ca908bfd +from.owls-122140-jdk8-ol87=cc7ee628-3750-489c-97f5-1e484d710e69 +from.owls-122140-jdk8-ol91=92f40d92-0786-4812-8918-a6f9dcc1b4ec +from.owls-141100-jdk8-ol87=5d011fae-34c1-4004-bd19-c2d2bccd30a4 +from.owls-141100-jdk8-ol91=9d76fbe1-3bbc-4a2b-a209-7427ad1db4ab +from.owls-141100-jdk11-ol87=459c178d-aec6-4bb5-8e80-66291f0ee6a8 +from.owls-141100-jdk11-ol91=5ce9afe5-c458-41b6-9b46-4899cde11806 +from.owls-141200-jdk21-ol94=ce0ed319-7470-4b49-ba87-a3ebcf49b303 +from.owls-141200-jdk21-ol810=2d0a20a6-3022-4142-8f46-6f84af1adc66 +from.owls-141200-jdk17-ol94=d3acf02b-e8f3-41ca-9e62-1318ab0c023b +from.owls-141200-jdk17-ol810=00d54634-1327-46bc-8a05-865aa648733d + + +# Pids to indicate which latest base image was chosen. No difference in these +# between Oracle and Microsoft +from.owls-122140-jdk8-rhel76=0a52f317-8b40-4a77-9f3c-7607fc3ebfb7wls +from.owls-141100-jdk8-rhel76=26ec5cf5-dd84-4764-97cf-4f830facbf66wls +from.owls-141100-jdk11-rhel76=ada2e3e6-faef-4339-aaac-40bcdc4484ecwls +from.owls-122140-jdk8-rhel87=6250babf-50f9-4462-a0c5-ebb8dc1ce5a7 +from.owls-141100-jdk8-rhel87=544e3e2c-d0a5-4615-87ff-2eadd5fefe5d +from.owls-141100-jdk11-rhel87=7c4a9f1d-ecdf-4fd3-bb68-0a28d8bea751 \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/pid.properties b/resources/pid.properties similarity index 57% rename from weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/pid.properties rename to resources/pid.properties index 637d18d2a..183acf541 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/pid.properties +++ b/resources/pid.properties @@ -1,22 +1,14 @@ # Copyright (c) 2021, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -azure.apiVersion=2020-06-01 -azure.apiVersion2=2019-06-01 -azure.apiVersionForDeploymentScript=2020-10-01 -azure.apiVersionForDNSZone=2018-05-01 -azure.apiVersionForIndentity=2018-11-30 -azure.apiVersionForKeyVault=2019-09-01 - - # Values in this file are read at build time for the other Azure Marketplace offer repositories -# Pids used in https://github.com/wls-eng/arm-oraclelinux-wls +# Pids used in https://github.com/oracle/weblogic-azure/tree/main/weblogic-azure-vm/arm-oraclelinux-wls -end=8f75aefd-02b2-50a8-9a6e-feb41176559f +end=pid-a63dea86-f8db-4e75-a231-1145d4f3ab6e-partnercenter start=b446fe15-5d43-5549-858d-4775741cd0ba -# Pids used in https://github.com/wls-eng/arm-oraclelinux-wls-admin +# Pids used in https://github.com/oracle/weblogic-azure/tree/main/weblogic-azure-vm/arm-oraclelinux-wls-admin admin.aad.end=d273da6e-9128-5163-a8e7-9f76505ae5cc admin.aad.start=0a77c1d0-cf1e-5185-89ad-230ffe24d0f8 @@ -27,9 +19,13 @@ admin.database.start=6b253477-1753-5eb1-9448-506ab47494d7 admin.elk.end=78d94c2d-7401-52a9-be03-4cf1cc4e8f00 admin.elk.start=f3c3b847-89ea-54c8-904e-10ff8eba14fa admin.end=057f09cd-6f90-5c1c-b655-3aba168aef35 -admin.start=18f4b80a-6ca2-5840-8f88-4e7156ed6db0 +admin.start=pid-7e52c2b6-1acb-416f-af55-5837ff783eb7-partnercenter +admin.ssl.end=7185f788-ab74-5158-8f83-4146d01cec9d +admin.ssl.start=2730ced3-52c2-501c-94b1-bfcffa5b5bc0 +admin.pswless.database.end=89d5d2a9-16b8-5b3d-b5f7-1fb8a6cfdfc5 +admin.pswless.database.start=53e099bf-8148-5463-a51d-0272520bac60 -# Pids used in https://github.com/wls-eng/arm-oraclelinux-wls-cluster +# Pids used in https://github.com/oracle/weblogic-azure/tree/main/weblogic-azure-vm/arm-oraclelinux-wls-cluster cluster.aad.end=3031eeaf-f67e-5f61-8bf1-aad6006eaf6d cluster.aad.start=cae84e84-407c-5cef-b2a0-cd95d4ff8824 @@ -37,6 +33,7 @@ cluster.addnode.end=2452bb0e-13d9-5ad3-816b-d645ba5198c4 cluster.addnode.start=ffa02caf-ecb9-59df-82ce-74b9b0247c50 cluster.addnode.coherence.end=157ea8ac-12ae-11eb-adc1-0242ac120002 cluster.addnode.coherence.start=157ea992-12ae-11eb-adc1-0242ac120002 +cluster.appgateway.custom.certificate=d7c730b9-494c-5cc2-9695-cc1057da3e0b cluster.appgateway.end=b626bee4-b322-5418-990f-6463a799be3c cluster.appgateway.start=4f85ce49-6de4-5925-b77c-3eb15ba97921 cluster.appgateway.keyvault.start=ed922d8d-975f-55d4-b33a-28fbace13f76 @@ -53,8 +50,12 @@ cluster.dns.end=022d99e3-8ba3-5822-b6d5-bcec64518286 cluster.dns.start=c40d7aa8-9fe7-51c6-86de-27e1b1678735 cluster.elk.end=cb84f8ed-d270-5036-8240-08b6bb4f2bd6 cluster.elk.start=c9bac63c-67eb-52e1-a8c1-2ba57f65cfbc +cluster.ssl.end=4f29ea52-dfd6-5537-8a38-4ad9fec1b2eb +cluster.ssl.start=e09585b6-b7cb-5437-a600-c95c88ac37b3 cluster.end=0fa14086-2d46-54a4-8aba-470addc3dce6 -cluster.start=2488df5d-5e73-5593-9d92-37b40999a9e0 +cluster.pswless.database.end=b4d91140-fb26-50de-9358-147b9dd25f7a +cluster.pswless.database.start=340f5265-6de7-5b6f-aad3-9f179736cde0 +cluster.start=pid-7363cd91-937d-4469-a7a8-ecbeddfb7a0f-partnercenter # Pids to indicate which database was chosen. No difference in these # between Oracle and Microsoft @@ -62,8 +63,9 @@ cluster.start=2488df5d-5e73-5593-9d92-37b40999a9e0 database.oracle=692b2d84-72f5-5992-a15d-0d5bcfef040d database.postgresql=935df06e-a5d5-5bf1-af66-4c1eb71dac7a database.sqlserver=3569588c-b89d-5567-84ee-a2c633c7204c +database.mysql=41c353ae-6f7b-442f-b903-996cb42c1bbe -# Pids used in https://github.com/wls-eng/arm-oraclelinux-wls-dynamic-cluster +# Pids used in https://github.com/oracle/weblogic-azure/tree/main/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster dynamic.aad.end=f5a60b13-efd6-551a-a40f-3923804e475d dynamic.aad.start=7dcc8904-9a8a-5b71-a73d-6caa9edb78ef @@ -84,21 +86,44 @@ dynamic.deletenode.end=3eb27f94-d1c3-572c-a7da-0d7f26f6a20e dynamic.elk.end=d154e480-15e2-5cf7-bdd5-6219c1793967 dynamic.elk.start=bc636673-2dca-5e40-a2aa-6891c344aa17 dynamic.end=93da13bf-11f6-5bfb-9b51-7deb152a21c3 -dynamic.start=2551958c-2465-5e2e-8e28-0b3a4babf3f0 +dynamic.start=pid-89d7f595-f164-4cbd-abbb-e46cd0b342e8-partnercenter +dynamic.ssl.end=325d251a-fcba-5bd8-ad50-5682b3565ef5 +dynamic.ssl.start=f6e45a7a-d491-58a1-a951-fad252e1a396 +dynamic.pswless.database.end=fd30aea8-ec77-557b-ba12-4de15018a64a +dynamic.pswless.database.start=2d02881c-c7d2-5e16-b9b8-c48ebf70d2ab # Pids to indicate which base image was chosen. No difference in these # between Oracle and Microsoft -from.owls-122130-8u131-ol74=ac3571f9-c12d-5caa-b886-85734693ab63 -from.owls-122130-8u131-ol73=2bd71be8-b31c-5fbf-96ba-61fde622586d +#from.owls-122130-8u131-ol74=ac3571f9-c12d-5caa-b886-85734693ab63 +#from.owls-122130-8u131-ol73=2bd71be8-b31c-5fbf-96ba-61fde622586d from.owls-122140-8u251-ol76=dd07bd44-828b-566a-8dc6-b84bf301bf1d from.owls-141100-8u251-ol76=cb2af004-23c3-5c85-87b9-9de767c7a61e from.owls-141100-11_07-ol76=632e8fde-e61f-57bf-af9d-5804bf00ecb3 # Pids to indicate which latest base image was chosen. -from.owls-122130-jdk8-ol74=40fe0044-5739-466c-96aa-0c82ab465d0b -from.owls-122130-jdk8-ol73=799fc764-af80-45c3-aea1-599f55901e73 +#from.owls-122130-jdk8-ol74=40fe0044-5739-466c-96aa-0c82ab465d0b +#from.owls-122130-jdk8-ol73=799fc764-af80-45c3-aea1-599f55901e73 from.owls-122140-jdk8-ol76=6637154a-06d2-4ac0-82ab-2a1d7e391eab from.owls-141100-jdk8-ol76=060d9c3f-cc20-4380-a383-fd20594e5b2a from.owls-141100-jdk11-ol76=3220431f-33d4-416a-8df7-a0fcc23a25e4 - +from.owls-122140-jdk8-ol87=f2ae4133-abd1-4711-ae74-aeb6e498f2c0 +from.owls-122140-jdk8-ol91=2b7d87a9-981a-44af-bf71-b2b479841ed9 +from.owls-141100-jdk8-ol87=d58854b4-a612-4fbf-b095-f2d2178a88df +from.owls-141100-jdk8-ol91=76d4dbe8-0679-4772-ad2e-461fac83dfd7 +from.owls-141100-jdk11-ol87=c8f1b07d-1660-4f6a-be97-3925645e8817 +from.owls-141100-jdk11-ol91=cd48f178-52a3-415e-88bb-caa45f615b94 +from.owls-141200-jdk21-ol94=6acfc3a0-6225-465f-9fa9-4d63ea81405b +from.owls-141200-jdk21-ol810=69146c30-9c7e-4ce2-8642-eb8eb1b23cc5 +from.owls-141200-jdk17-ol94=a9a1c9b7-6c27-4086-b271-1ffd3c215390 +from.owls-141200-jdk17-ol810=69b6b433-1679-4d37-af25-3d56987c217a + + +# Pids to indicate which latest base image was chosen. No difference in these +# between Oracle and Microsoft +from.owls-122140-jdk8-rhel76=0a52f317-8b40-4a77-9f3c-7607fc3ebfb7wls +from.owls-141100-jdk8-rhel76=26ec5cf5-dd84-4764-97cf-4f830facbf66wls +from.owls-141100-jdk11-rhel76=ada2e3e6-faef-4339-aaac-40bcdc4484ecwls +from.owls-122140-jdk8-rhel87=0799976a-84a5-4a59-b74b-bd67c4d37aa5 +from.owls-141100-jdk8-rhel87=2e471204-8cbe-4aec-9c64-4d0f5f8d590d +from.owls-141100-jdk11-rhel87=b1f76ba8-078d-43bc-b35c-9a4952eb00c9 \ No newline at end of file diff --git a/sbom_generation.yaml b/sbom_generation.yaml new file mode 100644 index 000000000..24f757d1d --- /dev/null +++ b/sbom_generation.yaml @@ -0,0 +1,22 @@ +# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + +# This OCI DevOps build specification file [1] generates a Software Bill of Materials (SBOM) of the repository. +# The file is needed to run checks for third-party vulnerabilities and business approval according to Oracle’s GitHub policies. +# [1] https://docs.oracle.com/en-us/iaas/Content/devops/using/build_specs.htm + +version: 0.1 +component: build +timeoutInSeconds: 1000 +shell: bash + +steps: + - type: Command + name: "Run Maven cycloneDX plugin command" + command: | + # For more details, visit https://github.com/CycloneDX/cyclonedx-maven-plugin/blob/master/README.md + mvn org.cyclonedx:cyclonedx-maven-plugin:2.7.9:makeAggregateBom -DincludeRuntimeScope=true -DincludeCompileScope=true -DincludeProvidedScope=false -DincludeSystemScope=false -DincludeTestScope=false -DoutputFormat=json -DoutputName=artifactSBOM -DschemaVersion=1.4 + mv target/artifactSBOM.json ${OCI_PRIMARY_SOURCE_DIR}/artifactSBOM.json +outputArtifacts: + - name: artifactSBOM + type: BINARY + location: ${OCI_PRIMARY_SOURCE_DIR}/artifactSBOM.json diff --git a/weblogic-azure-aks/README.md b/weblogic-azure-aks/README.md index b8e7b61ea..8725b2442 100644 --- a/weblogic-azure-aks/README.md +++ b/weblogic-azure-aks/README.md @@ -10,7 +10,7 @@ The [Azure Marketplace WebLogic Server Offering](https://azuremarketplace.micros ## Documentation -Please refer to the documentation sample [Oracle WebLogic Server Azure Applications](https://oracle.github.io/weblogic-kubernetes-operator/samples/simple/azure-kubernetes-service/) +Please refer to the documentation sample [Oracle WebLogic Server Azure Applications](https://aka.ms/wls-aks-docs-sample) ## Examples diff --git a/weblogic-azure-aks/pom.xml b/weblogic-azure-aks/pom.xml index fa63fa571..32522acc5 100644 --- a/weblogic-azure-aks/pom.xml +++ b/weblogic-azure-aks/pom.xml @@ -1,28 +1,39 @@ - - 4.0.0 + + 4.0.0 - + + - com.oracle.weblogic.azure - wls-on-aks-azure-marketplace - 1.0.18 + + com.oracle.weblogic.azure + weblogic-azure + 1.0.0 + - - com.microsoft.azure.iaas - azure-javaee-iaas-parent - 1.0.10 - - + com.oracle.weblogic.azure + wls-on-aks-azure-marketplace + ${version.wls-on-aks-azure-marketplace} + + jar + wls-on-aks-azure-marketplace + + + ${project.basedir}/.. + + false + false + - jar - wls-on-aks-azure-marketplace - - -TestParameter '@{"PasswordMinLength"=6}' - diff --git a/weblogic-azure-aks/src/main/arm/createUiDefinition.json b/weblogic-azure-aks/src/main/arm/createUiDefinition.json index 812fac057..7600b9c04 100644 --- a/weblogic-azure-aks/src/main/arm/createUiDefinition.json +++ b/weblogic-azure-aks/src/main/arm/createUiDefinition.json @@ -3,12 +3,36 @@ "handler": "Microsoft.Azure.CreateUIDef", "version": "0.1.2-preview", "parameters": { + "config": { + "basics": { + "resourceGroup": { + "allowExisting": true + } + } + }, "basics": [ + { + "name": "infoForBeforeDeployment", + "type": "Microsoft.Common.InfoBox", + "visible": true, + "options": { + "icon": "Info", + "text": "The Azure identity deploying this offer must have one of the following two sets of Azure role-based access control roles:
  • Contributor and User Access Administrator of the current subscription.
  • Owner of the current subscription.
  • " + } + }, { "name": "basicsRequired", "type": "Microsoft.Common.Section", "label": "Credentials for WebLogic", "elements": [ + { + "name": "listVMSizes", + "type": "Microsoft.Solutions.ArmApiControl", + "request": { + "method": "GET", + "path": "[concat(subscription().id, '/providers/Microsoft.Compute/locations/',location(),'/vmSizes?api-version=2024-03-01')]" + } + }, { "name": "wlsUserName", "type": "Microsoft.Common.TextBox", @@ -21,10 +45,6 @@ { "regex": "^[a-z0-9A-Z]{1,30}$", "message": "The value must be 1-30 characters long and must only contain letters and numbers." - }, - { - "isValid": "[greaterOrEquals(length(basics('basicsRequired').identity.userAssignedIdentities),1)]", - "message": "Please select at least one user assigned managed identity from User assigned managed identity control below." } ] }, @@ -52,10 +72,10 @@ "name": "wdtRuntimePassword", "type": "Microsoft.Common.PasswordBox", "label": { - "password": "Password for WebLogic Deploy Tooling runtime encrytion", + "password": "Password for WebLogic Model encryption", "confirmPassword": "Confirm password" }, - "toolTip": "The model WebLogic Deploy Tooling runtime encrytion secret.", + "toolTip": "Model in Image requires a runtime encryption secret with a secure `password` key. This secret is used by the operator to encrypt model and domain home artifacts before it adds them to a runtime ConfigMap or log. See https://aka.ms/wls-aks-model-runtime-encryption-secret.", "constraints": { "required": true, "regex": "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)[A-Za-z\\d]{12,}$", @@ -65,72 +85,6 @@ "hideConfirmation": false }, "visible": true - }, - { - "name": "ocrSSOInfo", - "type": "Microsoft.Common.InfoBox", - "visible": true, - "options": { - "icon": "Info", - "text": "Provide an Oracle Single Sign-On (SSO) account to access the Oracle Registry Server. Click the link to create Oracle SSO account.", - "uri": "https://profile.oracle.com/myprofile/account/create-account.jspx" - } - }, - { - "name": "ocrSSOUserName", - "type": "Microsoft.Common.TextBox", - "label": "Username for Oracle Single Sign-On authentication", - "defaultValue": "example@contoso.com", - "toolTip": "Username for Oracle Single Sign-On authentication to login the Oracle Container Registry.", - "constraints": { - "required": true, - "regex": "^([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$", - "validationMessage": "The value must be an email address." - }, - "visible": true - }, - { - "name": "ocrSSOPassword", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Password for Oracle Single Sign-On authentication", - "confirmPassword": "Confirm password" - }, - "toolTip": "Password for Oracle Single Sign-On authentication to login the Oracle Container Registry.", - "constraints": { - "required": true, - "regex": "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)[A-Za-z\\d\\$\\&\\+\\,:\\=\\?@#|'.\\^\\*!\\-_~/'\\[\\]\\{\\}\"]{8,}$", - "validationMessage": "The password must contain at least 8 characters, with at least 1 uppercase letter, 1 lowercase letter and 1 number, and special characters, but should not contain > < ( ) % ; \\." - }, - "options": { - "hideConfirmation": false - }, - "visible": true - }, - { - "name": "errInfo", - "type": "Microsoft.Common.InfoBox", - "visible": "[less(length(basics('basicsRequired').identity.userAssignedIdentities),1)]", - "options": { - "icon": "Error", - "text": "Please select at least one user assigned managed identity.", - "uri": "https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-to-manage-ua-identity-portal" - } - }, - { - "name": "identity", - "type": "Microsoft.ManagedIdentity.IdentitySelector", - "label": "Managed Identity Configuration", - "toolTip": { - "userAssignedIdentity": "Add user assigned identities to enable the WebLogic domain deployment." - }, - "defaultValue": { - "systemAssignedIdentity": "Off" - }, - "options": { - "hideSystemAssignedIdentity": true, - "hideUserAssignedIdentity": false - } } ], "visible": true @@ -204,10 +158,10 @@ "type": "Microsoft.Common.Slider", "min": 5, "max": 1000, - "label": "Cluster size", + "label": "Maximum dynamic cluster size", "defaultValue": 5, "showStepMarkers": false, - "toolTip": "The maximum size of the WebLogic cluster.", + "toolTip": "The maximum size of the dynamic WebLogic cluster.", "constraints": { "required": true }, @@ -225,17 +179,31 @@ }, "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" }, + { + "name": "enableT3TunnelingTextBlock", + "type": "Microsoft.Common.TextBlock", + "visible": false, + "options": { + "text": "If checked, configure the necessary settings to enable T3 tunneling. You must take additional action on the Networking tab if either of these are checked.", + "link": { + "label": "Learn more", + "uri": "https://aka.ms/wls-aks-t3-tunneling" + } + } + }, { "name": "enableAdminT3Tunneling", "type": "Microsoft.Common.CheckBox", - "label": "Enable T3 tunneling for Admin Server", - "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" + "label": "Enable T3 tunneling for Administration Server", + "toolTip": "If checked, enable T3 tunneling for Administration Server", + "visible": false }, { "name": "enableClusterT3Tunneling", "type": "Microsoft.Common.CheckBox", "label": "Enable T3 tunneling for WebLogic cluster", - "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" + "toolTip": "If checked, enable T3 tunneling for WebLogic cluster.", + "visible": false } ], "visible": true @@ -245,6 +213,18 @@ "type": "Microsoft.Common.Section", "label": "Report issues, get help, and share feedback", "elements": [ + { + "name": "help", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "See the documentation for this offer in the Oracle WebLogic Kubernetes Operator.", + "link": { + "label": "Offer documentation", + "uri": "https://aka.ms/wls-aks-docs" + } + } + }, { "name": "howToReportIssueText", "type": "Microsoft.Common.TextBlock", @@ -253,7 +233,7 @@ "text": "If you encounter problems during the deployment of Oracle WebLogic Server, report them here.", "link": { "label": "Issue tracker", - "uri": "https://aka.ms/arm-oraclelinux-wls-issues" + "uri": "https://aka.ms/arm-oraclelinux-wls-issues?version=${project.version}" } } }, @@ -283,26 +263,17 @@ } ], "visible": true - }, - { - "name": "About", - "type": "Microsoft.Common.InfoBox", - "options": { - "icon": "None", - "text": "Template version ${project.version}" - }, - "visible": "[bool('${template.version.visible}')]" } ], "steps": [ { "name": "section_aks", - "label": "Configure AKS cluster", + "label": "AKS", "subLabel": { "preValidation": "Provide required info for AKS cluster configuration", "postValidation": "Done" }, - "bladeTitle": "Configure AKS cluster", + "bladeTitle": "AKS", "elements": [ { "name": "clusterInfo", @@ -329,6 +300,14 @@ "required": true } }, + { + "name": "infoBoxAks", + "type": "Microsoft.Common.InfoBox", + "visible": "[not(bool(steps('section_aks').clusterInfo.createAKSCluster))]", + "options": { + "text": "Ensure that the AKS cluster is configured with the following networking settings:
  • Container networking: Azure CNI Node Subnet
  • Network policy: Azure
  • " + } + }, { "name": "aksClusterSelector", "type": "Microsoft.Solutions.ResourceSelector", @@ -344,32 +323,76 @@ "visible": "[not(bool(steps('section_aks').clusterInfo.createAKSCluster))]" }, { - "name": "aksNodeCount", - "type": "Microsoft.Common.Slider", - "min": 1, - "max": 1000, - "label": "Node count", - "defaultValue": 2, - "showStepMarkers": false, - "toolTip": "The number of nodes that should be created along with the cluster. You will be able to resize the cluster later.", - "constraints": { - "required": true - }, - "visible": "[bool(steps('section_aks').clusterInfo.createAKSCluster)]" + "name": "aksSupportedVersionTextBlock", + "type": "Microsoft.Common.TextBlock", + "visible": "[bool(steps('section_aks').clusterInfo.createAKSCluster)]", + "options": { + "icon": "Info", + "text": "AKS supports a range of Kubernetes versions. This offer is tested with a specific Kubernetes version known to work with WebLogic Server on AKS; click 'Learn more' to find the version information.", + "link": { + "label": "Learn more", + "uri": "https://aka.ms/wls-aks-well-tested-version" + } + } }, { "name": "nodeVMSizeSelector", "type": "Microsoft.Compute.SizeSelector", - "label": "Size", - "toolTip": "", + "label": "Node size", + "toolTip": "The size of virtual machine to provision.", "recommendedSizes": [ "Standard_DS2_v2" ], "constraints": { - "allowedSizes": [], - "excludedSizes": [], - "numAvailabilityZonesRequired": 3, - "zone": "3" + "excludedSizes": [ + "Standard_A0", + "Standard_A1", + "Standard_A1_v2", + "Standard_F1", + "Standard_F1s", + "Standard_DS1_v2", + "Standard_B12ms", + "Standard_B16als_v2", + "Standard_B16as_v2", + "Standard_B16ls_v2", + "Standard_B16ms", + "Standard_B16pls_v2", + "Standard_B16ps_v2", + "Standard_B16s_v2", + "Standard_B1ls", + "Standard_B1ms", + "Standard_B1s", + "Standard_B20ms", + "Standard_B2als_v2", + "Standard_B2as_v2", + "Standard_B2ats_v2", + "Standard_B2ls_v2", + "Standard_B2ms", + "Standard_B2pls_v2", + "Standard_B2ps_v2", + "Standard_B2pts_v2", + "Standard_B2s", + "Standard_B2s_v2", + "Standard_B2ts_v2", + "Standard_B32als_v2", + "Standard_B32as_v2", + "Standard_B32ls_v2", + "Standard_B32s_v2", + "Standard_B4als_v2", + "Standard_B4as_v2", + "Standard_B4ls_v2", + "Standard_B4ms", + "Standard_B4pls_v2", + "Standard_B4ps_v2", + "Standard_B4s_v2", + "Standard_B8als_v2", + "Standard_B8as_v2", + "Standard_B8ls_v2", + "Standard_B8ms", + "Standard_B8pls_v2", + "Standard_B8ps_v2", + "Standard_B8s_v2" + ] }, "options": { "hideDiskTypeFilter": false @@ -379,28 +402,45 @@ "visible": "[bool(steps('section_aks').clusterInfo.createAKSCluster)]" }, { - "name": "enableAzureMonitoring", - "type": "Microsoft.Common.CheckBox", - "label": "Enable Azure Monitoring", + "name": "aksNodeCount", + "type": "Microsoft.Common.Slider", + "min": "[add(1, div(add(12288, mul(if(bool(basics('basicsOptional').basicsOptionalAcceptDefaults), basics('basicsOptional').wlsClusterSize, 5), 1536)), first(filter(basics('basicsRequired').listVMSizes.value, (item) => equals(item.name, steps('section_aks').clusterInfo.nodeVMSizeSelector))).memoryInMB))]", + "defaultValue": 3, + "max": 998, + "label": "Minimum node count", + "showStepMarkers": false, + "toolTip": "Set the minimum node count for the cluster.", + "constraints": { + "required": true + }, "visible": "[bool(steps('section_aks').clusterInfo.createAKSCluster)]" }, { - "name": "enableAzureFileShare", - "type": "Microsoft.Common.CheckBox", - "label": "Create Persistent Volume using Azure File share service", + "name": "aksNodeMaxCount", + "type": "Microsoft.Common.Slider", + "min": "[add(steps('section_aks').clusterInfo.aksNodeCount,2)]", + "defaultValue": 3, + "max": 1000, + "label": "Maximum node count", + "showStepMarkers": false, + "toolTip": "Set the maximum node count for the cluster.", + "constraints": { + "required": true + }, "visible": "[bool(steps('section_aks').clusterInfo.createAKSCluster)]" } ] }, { - "name": "acrInfo", + "name": "imageInfo", "type": "Microsoft.Common.Section", - "label": "Azure Container Registry", + "label": "Image selection", "elements": [ { - "name": "createACR", + "name": "oracleCreateACR", "type": "Microsoft.Common.OptionsGroup", - "label": "Create a new ACR instance?", + "visible": true, + "label": "Create a new Azure Container Registry to store application images?", "defaultValue": "Yes", "toolTip": "Select 'Yes' to create a new ACR instance, or select 'No' to provide an existing ACR instance.", "constraints": { @@ -418,17 +458,17 @@ } }, { - "name": "acrInfo", + "name": "oracleAcrInfo", "type": "Microsoft.Common.InfoBox", - "visible": "[not(bool(steps('section_aks').acrInfo.createACR))]", + "visible": "[not(bool(steps('section_aks').imageInfo.oracleCreateACR))]", "options": { "icon": "Info", - "text": "Make sure the Azure Container Registry has enabled admin user.", + "text": "Make sure the Azure Container Registry has enabled the admin user.", "uri": "https://docs.microsoft.com/en-us/azure/container-registry/container-registry-authentication#admin-account" } }, { - "name": "acrSelector", + "name": "oracleAcrSelector", "type": "Microsoft.Solutions.ResourceSelector", "label": "Select ACR instance", "toolTip": "Select the existing ACR instance.", @@ -439,34 +479,165 @@ "location": "onBasics" } }, - "visible": "[not(bool(steps('section_aks').acrInfo.createACR))]" - } - ] - }, - { - "name": "imageInfo", - "type": "Microsoft.Common.Section", - "label": "Oracle WebLogic Image", - "elements": [ + "visible": "[not(bool(steps('section_aks').imageInfo.oracleCreateACR))]" + }, { - "name": "fromImageText", - "type": "Microsoft.Common.TextBlock", + "name": "ocrSSOInfo", + "type": "Microsoft.Common.InfoBox", "visible": true, "options": { - "text": "This value is appended to 'container-registry.oracle.com/middleware/weblogic:' and used in the Dockerfile from statement. \nOracle Standard Terms and Restrictions terms must be agreed. \nClick the following link to make sure you have agree the terms and check the valid tags.", - "link": { - "label": "Must be a valid tag value from Oracle Container Registry", - "uri": "https://aka.ms/wls-aks-fromImage-tag?${project.version}-${maven.build.timestamp}" - } + "icon": "Info", + "text": "Provide an Oracle Single Sign-On (SSO) account to access the Oracle Registry Server. Select the link to create an Oracle SSO account.", + "uri": "https://aka.ms/wls-aks-create-sso-account" + } + }, + { + "name": "ocrSSOUserName", + "type": "Microsoft.Common.TextBox", + "label": "Username for Oracle Single Sign-On authentication", + "defaultValue": "example@contoso.com", + "toolTip": "Username for Oracle Single Sign-On authentication to login the Oracle Container Registry.", + "constraints": { + "required": true, + "regex": "^([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$", + "validationMessage": "The value must be an email address." + }, + "visible": true + }, + { + "name": "ocrSSOTokenInfo", + "type": "Microsoft.Common.InfoBox", + "visible": true, + "options": { + "icon": "Info", + "text": "Please use an Auth Token associated with an SSO user. Select the link to see more details.", + "uri": "https://aka.ms/wls-auth-token" + } + }, + { + "name": "ocrSSOPassword", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Auth token for Oracle Single Sign-On authentication", + "confirmPassword": "Confirm token" + }, + "toolTip": "Auth token for Oracle Single Sign-On authentication to login the Oracle Container Registry.", + "constraints": { + "required": true, + "regex": "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)[A-Za-z\\d\\$\\&\\+\\,:\\=\\?@#|'.\\^\\*!\\-_~/'\\[\\]\\{\\}\"]{8,}$", + "validationMessage": "The token must contain at least 8 characters, with at least 1 uppercase letter, 1 lowercase letter and 1 number, and special characters, but should not contain > < ( ) % ; \\." + }, + "options": { + "hideConfirmation": false + }, + "visible": true + }, + { + "name": "fromImageInfo", + "type": "Microsoft.Common.InfoBox", + "visible": true, + "options": { + "icon": "Warning", + "text": "Before moving forward, you must accept the Oracle Standard Terms and Restrictions for the WebLogic Server
    image in the Oracle Container Registry (OCR). The deployment will fail if you have not accepted the terms.

    If you have an Oracle support contract, we recommend using the Patched WebLogic Server Images.
    Otherwise, you can use the General WebLogic Server Images.

    To use the General WebLogic Server Images:To use the Patched WebLogic Server Images:Once you have accepted the terms in OCR, make sure to select the right type of image below." } }, { - "name": "fromImage", + "name": "isSSOSupportEntitled", + "type": "Microsoft.Common.OptionsGroup", + "label": "Select the type of WebLogic Server Images.", + "defaultValue": "General WebLogic Server Images", + "toolTip": "If 'Patched WebLogic Server Images' is selected, the deployment process will pull from the Patched WebLogic Server Images repository. If 'General WebLogic Server Images' is selected the deployment process will pull from the General WebLogic Server Images repository.", + "constraints": { + "allowedValues": [ + { + "label": "General WebLogic Server Images", + "value": "false" + }, + { + "label": "Patched WebLogic Server Images", + "value": "true" + } + ], + "required": true + }, + "visible": true + }, + { + "name": "oracleImageSelector", + "type": "Microsoft.Common.DropDown", + "label": "Select desired combination of WebLogic Server, JDK and Operating System or fully qualified Docker tag", + "defaultValue": "14.1.2.0-17-ol9", + "multiLine": true, + "toolTip": "Select image", + "constraints": { + "allowedValues": [ + { + "label": "14.1.2.0-17-ol9", + "description": "14c (14.1.2.0) on JDK 17 on Oracle Linux 9", + "value": "14.1.2.0-generic-jdk17-ol9" + }, + { + "label": "14.1.2.0-21-ol9", + "description": "14c (14.1.2.0) on JDK 21 on Oracle Linux 9", + "value": "14.1.2.0-generic-jdk21-ol9" + }, + { + "label": "14.1.2.0-17-ol8", + "description": "14c (14.1.2.0) on JDK 17 on Oracle Linux 8", + "value": "14.1.2.0-generic-jdk17-ol8" + }, + { + "label": "14.1.2.0-21-ol8", + "description": "14c (14.1.2.0) on JDK 21 on Oracle Linux 8", + "value": "14.1.2.0-generic-jdk21-ol8" + }, + { + "label": "14.1.1.0-8", + "description": "14c (14.1.1.0) on JDK 8 on Oracle Linux 7", + "value": "14.1.1.0-8" + }, + { + "label": "14.1.1.0-11", + "description": "14c (14.1.1.0) on JDK 11 on Oracle Linux 7", + "value": "14.1.1.0-11" + }, + { + "label": "12.2.1.4", + "description": "12cR2 (12.2.1.4) on JDK 8 on Oracle Linux 7", + "value": "12.2.1.4" + }, + { + "label": "14.1.1.0-8-ol8", + "description": "14c (14.1.1.0.0) on JDK 8 on Oracle Linux 8", + "value": "14.1.1.0-8-ol8" + }, + { + "label": "14.1.1.0-11-ol8", + "description": "14c (14.1.1.0.0) on JDK 11 on Oracle Linux 8", + "value": "14.1.1.0-11-ol8" + }, + { + "label": "12.2.1.4-ol8", + "description": "12cR2 (12.2.1.4) on JDK 8 on Oracle Linux 8", + "value": "12.2.1.4-ol8" + }, + { + "label": "Others", + "description": "Specify fully qualified Oracle Container Registry tag", + "value": "others" + } + ], + "required": true + }, + "visible": true + }, + { + "name": "fromOracleImage", "type": "Microsoft.Common.TextBox", + "visible": "[equals(steps('section_aks').imageInfo.oracleImageSelector, 'others')]", "label": "WebLogic Docker tag", - "defaultValue": "12.2.1.4-ol8", - "toolTip": "Docker tag that comes after 'container-registry.oracle.com/middleware/weblogic:' in the fromImage option to 'imagetool'.", - "multiLine": false, + "defaultValue": "14.1.1.0-slim-11", + "toolTip": "Docker tag that comes after 'container-registry.oracle.com/middleware/weblogic:' in the fromOracleImage option to 'imagetool'.", "constraints": { "required": true, "validations": [ @@ -476,6 +647,15 @@ } ] } + }, + { + "name": "unsupportedPlatformInfo1", + "type": "Microsoft.Common.InfoBox", + "visible": "[and(contains(steps('section_aks').clusterInfo.nodeVMSizeSelector,'p'), contains(parse('[\"14.1.1.0-11\", \"14.1.1.0-8\", \"14.1.1.0-slim-11\", \"14.1.1.0-slim-8\", \"12.2.1.4\", \"12.2.1.4-slim\"]'),if(equals(steps('section_aks').imageInfo.oracleImageSelector, 'others'), steps('section_aks').imageInfo.fromOracleImage, steps('section_aks').imageInfo.oracleImageSelector)))]", + "options": { + "icon": "Error", + "text": "The selected image is not compatible with the ARM64 platform. Please choose a different image or select a different size from AKS -> Azure Kubernetes Service -> Node size. For more information, see the Azure documentation." + } } ], "visible": true @@ -483,14 +663,14 @@ { "name": "jeeAppInfo", "type": "Microsoft.Common.Section", - "label": "Java EE Application", + "label": "Application", "elements": [ { "name": "uploadAppPackage", "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy your application package?", - "defaultValue": "Yes", - "toolTip": "Select 'Yes' to deploy your application, or select 'No' to deploy a default 'hello world' open liberty application.", + "label": "Deploy an application?", + "defaultValue": "No", + "toolTip": "Select 'Yes' to deploy your application.", "constraints": { "allowedValues": [ { @@ -505,6 +685,15 @@ "required": true } }, + { + "name": "appInfoBox", + "type": "Microsoft.Common.InfoBox", + "options": { + "icon": "Info", + "text": "You must select the application files from Azure Storage Account.
    Follow the steps to upload your applications to an Azure Storage Account:
  • Create a Storage Account
  • Create a container and upload application files
  • " + }, + "visible": "[bool(steps('section_aks').jeeAppInfo.uploadAppPackage)]" + }, { "name": "appPackageUrl", "type": "Microsoft.Common.FileUpload", @@ -521,86 +710,193 @@ }, "visible": "[bool(steps('section_aks').jeeAppInfo.uploadAppPackage)]" }, + { + "name": "validateApplicationsInfo", + "type": "Microsoft.Common.InfoBox", + "visible": false, + "options": { + "icon": "Info", + "text": "If checked, verify the deployed app reaches the ACTIVE state and fail the deployment if it does not. See the documentation link for more information.", + "uri": "https://aka.ms/wls-aks-deployment-state" + } + }, + { + "name": "validateApplications", + "type": "Microsoft.Common.CheckBox", + "label": "Fail deployment if application does not become ACTIVE.", + "toolTip": "If checked, verify the deployed app reaches the ACTIVE state and fail the deployment if it does not. See the documentation link for more information.", + "visible": false + }, { "name": "appReplicas", "type": "Microsoft.Common.TextBox", - "label": "Number of application replicas", + "label": "Number of WebLogic Managed Server replicas", "defaultValue": "2", - "toolTip": "The number of application replicas to deploy.", + "toolTip": "The number of WebLogic Managed Server replicas to deploy.", "constraints": { "required": true, - "regex": "^(1|2|3|4|5)$", - "validationMessage": "Number of application replicas to deploy, limit 1-5." + "regex": "^(1|2|3|4|5){1}$", + "validationMessage": "Number of WebLogic Managed Server replicas to deploy, limit 1-5." } } ], "visible": true - } - ] - }, - { - "name": "section_sslConfiguration", - "type": "Microsoft.Common.Section", - "label": "TLS/SSL Configuration", - "elements": [ - { - "name": "sslConfigurationText", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "Selecting 'Yes' here will cause the template to provision WebLogic Administration Console, Remote Console, cluster and custom T3 channel on HTTPS (Secure) port, with your own TLS/SSL certificate.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-ssl-config" - } - } }, { - "name": "enableCustomSSL", + "name": "aksAdvancedConfig", "type": "Microsoft.Common.OptionsGroup", - "label": "Configure end to end TLS/SSL to WebLogic Administration Console and cluster on HTTPS (Secure) port, with your own certificate?", + "label": "Show advanced configuration?", "defaultValue": "No", - "toolTip": "Select 'Yes' to configure end to end TLS/SSL to WebLogic Administration Console and cluster on HTTPS (Secure) port, with your own certificate.", + "toolTip": "Select 'Yes' to edit advanced configuration.", "constraints": { "allowedValues": [ { "label": "Yes", - "value": true + "value": "true" }, { "label": "No", - "value": false + "value": "false" } ], - "required": false + "required": true } }, { - "name": "sslConfigurationAccessOption", - "type": "Microsoft.Common.OptionsGroup", - "visible": "[steps('section_sslConfiguration').enableCustomSSL]", - "label": "How would you like to provide required configuration", - "defaultValue": "Upload existing KeyStores", - "toolTip": "Select 'Upload existing KeyStores' to use local stored KeyStores.", - "constraints": { - "allowedValues": [ - { - "label": "Upload existing KeyStores", - "value": "uploadConfig" - }, - { - "label": "Use KeyStores stored in Azure Key Vault", - "value": "keyVaultStoredConfig" - } - ], - "required": false + "name": "aksAdvancedInfo", + "type": "Microsoft.Common.Section", + "label": "Advanced", + "elements": [ + { + "name": "enableAzureMonitoringTextBlock", + "type": "Microsoft.Common.TextBlock", + "visible": "[bool(steps('section_aks').clusterInfo.createAKSCluster)]", + "options": { + "icon": "Info", + "text": "If checked, configure the necessary settings to integrate with Container insights. Container insights gives you performance visibility by collecting memory and processor metrics from controllers, nodes, and containers that are available in Kubernetes through the Metrics API. Container logs are also collected. Metrics are written to the metrics store and log data is written to the logs store associated with your Log Analytics workspace.", + "link": { + "label": "Learn more", + "uri": "https://aka.ms/wls-aks-container-insights" + } + } + }, + { + "name": "enableAzureMonitoring", + "type": "Microsoft.Common.CheckBox", + "label": "Enable Container insights", + "toolTip": "If checked, configure the necessary settings to integrate with Container insights.", + "visible": "[bool(steps('section_aks').clusterInfo.createAKSCluster)]" + }, + { + "name": "enableAzureFileShareTextBlock", + "type": "Microsoft.Common.TextBlock", + "visible": "[bool(steps('section_aks').clusterInfo.createAKSCluster)]", + "options": { + "icon": "Info", + "text": "If checked, configure the necessary settings to mount a persistent volume to the nodes of the AKS cluster. This can be useful for storing log files outside of the AKS cluster, among other possible uses. An Azure Storage Account and an Azure Files share will be provisioned; static persistent volume with the Azure Files share will be mounted to the nodes of the AKS cluster.", + "link": { + "label": "Learn more", + "uri": "https://aka.ms/wls-aks-persistent-storage" + } + } + }, + { + "name": "enableAzureFileShare", + "toolTip": "If checked, configure the necessary settings to mount a persistent volume to the nodes of the AKS cluster.", + "type": "Microsoft.Common.CheckBox", + "label": "Create Persistent Volume using Azure File share service", + "visible": "[bool(steps('section_aks').clusterInfo.createAKSCluster)]" + }, + { + "name": "useAcrImage", + "type": "Microsoft.Common.CheckBox", + "label": "Bring your own WebLogic Server Docker image from Azure Container Registry?", + "toolTip": "Select 'Yes' to use a pre-existing Docker image, assumed to be a compatible WebLogic Server image, from the specified ACR instance. This allows the use of custom images, such as with a specific set of patches (PSUs)." + }, + { + "name": "userProvidedAcrInfo", + "type": "Microsoft.Common.InfoBox", + "visible": "[bool(steps('section_aks').aksAdvancedInfo.useAcrImage)]", + "options": { + "icon": "Info", + "text": "Make sure the Azure Container Registry has enabled the admin user.", + "uri": "https://docs.microsoft.com/en-us/azure/container-registry/container-registry-authentication#admin-account" + } + }, + { + "name": "userProvidedAcrSelector", + "type": "Microsoft.Solutions.ResourceSelector", + "label": "Select existing ACR instance", + "toolTip": "Select the existing ACR instance.", + "resourceType": "Microsoft.ContainerRegistry/registries", + "options": { + "filter": { + "subscription": "onBasics", + "location": "onBasics" + } + }, + "visible": "[bool(steps('section_aks').aksAdvancedInfo.useAcrImage)]" + }, + { + "name": "userProvidedImagePath", + "type": "Microsoft.Common.TextBox", + "visible": "[bool(steps('section_aks').aksAdvancedInfo.useAcrImage)]", + "label": "Please provide the image path", + "toolTip": "Please provide the image path, the image must be stored in the selected ACR above", + "defaultValue": "", + "constraints": { + "required": true, + "regex": "[concat(coalesce(last(split(steps('section_aks').aksAdvancedInfo.userProvidedAcrSelector.id, '/')), ''), '.*$')]", + "validationMessage": "The image must be stored in the selected ACR above" + } + } + ], + "visible": "[bool(steps('section_aks').aksAdvancedConfig)]" + } + ] + }, + { + "name": "section_sslConfiguration", + "type": "Microsoft.Common.Section", + "label": "TLS/SSL", + "elements": [ + { + "name": "sslConfigurationText", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "Selecting 'Yes' here will cause the offer to configure WebLogic Server Administration Console, Remote Console and cluster to use HTTPS (Secure) ports, with your own TLS/SSL certificate.", + "link": { + "label": "Learn more", + "uri": "https://aka.ms/arm-oraclelinux-wls-ssl-config" + } } }, + { + "name": "enableCustomSSL", + "type": "Microsoft.Common.OptionsGroup", + "label": "Configure end to end TLS/SSL to WebLogic Server Administration Console and cluster on HTTPS (Secure) port, with your own certificate?", + "defaultValue": "No", + "toolTip": "Select 'Yes' to configure end to end TLS/SSL to WebLogic Server Administration Console and cluster on HTTPS (Secure) port, with your own certificate.", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": true + }, + { + "label": "No", + "value": false + } + ], + "required": false + } + }, { "name": "uploadedCustomSSLSettings", "type": "Microsoft.Common.Section", - "visible": "[and(steps('section_sslConfiguration').enableCustomSSL, equals(steps('section_sslConfiguration').sslConfigurationAccessOption, 'uploadConfig'))]", - "label": "TLS/SSL Configuration Settings", + "visible": "[steps('section_sslConfiguration').enableCustomSSL]", + "label": "TLS/SSL configuration settings", "elements": [ { "name": "sslKeystoreInfo0", @@ -754,218 +1050,254 @@ } } ] + } + ] + }, + { + "name": "section_appGateway", + "type": "Microsoft.Common.Section", + "label": "Load balancing", + "subLabel": { + "preValidation": "Provide required information for load balancing", + "postValidation": "Done" + }, + "bladeTitle": "Load balancing", + "elements": [ + { + "name": "connectToAGText", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "This blade allows configuring options for load balancing and ingress controller." + } + }, + { + "name": "loadBalancingOptions", + "type": "Microsoft.Common.OptionsGroup", + "label": "Load Balancing Options", + "defaultValue": "Application Gateway Ingress Controller", + "toolTip": "Select load balancing option.", + "constraints": { + "allowedValues": [ + { + "label": "Application Gateway Ingress Controller", + "value": "agic" + }, + { + "label": "Standard Load Balancer Service", + "value": "lbservice" + }, + { + "label": "No Load Balancer", + "value": "none" + } + ], + "required": true + }, + "visible": true }, { - "name": "keyVaultStoredCustomSSLSettings", + "name": "appgwIngress", "type": "Microsoft.Common.Section", - "visible": "[and(steps('section_sslConfiguration').enableCustomSSL, equals(steps('section_sslConfiguration').sslConfigurationAccessOption, 'keyVaultStoredConfig'))]", - "label": "TLS/SSL Configuration Settings", + "label": "Application Gateway Ingress Controller", "elements": [ { - "name": "sslKeystoreInfo1", - "type": "Microsoft.Common.InfoBox", - "visible": "true", - "options": { - "icon": "Info", - "text": "You must provide different files for identity and trust KeyStores. Select here for more details.", - "uri": "https://aka.ms/arm-oraclelinux-wls-ssl-configuration" - } - }, - { - "name": "keyVaultText", + "name": "enableAppGatewayText", "type": "Microsoft.Common.TextBlock", - "visible": "true", + "visible": true, "options": { - "text": "Enabling a HTTPS (Secure) port for the Administration Console requires you to obtain a valid TLS/SSL certificate. The template will look for the certificate and other configuration items in the Azure Key Vault specified here.", + "text": "This option will cause the offer to configure an Application Gateway Ingress Controller", "link": { "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-cluster-app-gateway-key-vault" + "uri": "https://aka.ms/wls-aks-app-gateway-ingress-controller" } } }, { - "name": "keyVaultResourceGroup", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "Resource group name in current subscription containing the Key Vault", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1})$", - "validationMessage": "[if(greater(length(steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultResourceGroup), 90),'Resource group names only allow up to 90 characters.', 'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" + "name": "vnetInfo", + "type": "Microsoft.Common.InfoBox", + "visible": true, + "options": { + "icon": "Info", + "text": "When creating a new virtual network, the subnet's address prefix is calculated automatically based on the virtual
    network's address prefix. When using an existing virtual network, a minimum virtual network size of /24 and a
    minimum subnet size of /24 are required. Additionally, the subnet must be dedicated only for use by the
    Application Gateway." } }, { - "name": "keyVaultName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "Name of the Azure Key Vault containing secrets for the TLS/SSL certificate", - "defaultValue": "", - "toolTip": "Use only letters and numbers", + "name": "vnetForApplicationGateway", + "type": "Microsoft.Network.VirtualNetworkCombo", + "label": { + "virtualNetwork": "Virtual network", + "subnets": "Subnets" + }, + "toolTip": { + "virtualNetwork": "Select a virtual network in which to place the Application Gateway.", + "subnets": "The subnet must be dedicated only for use by the Application Gateway." + }, + "defaultValue": { + "name": "[concat('wlsaks-vnet',take(guid(), 8))]", + "addressPrefixSize": "/24" + }, "constraints": { - "required": true, - "regex": "^(?=.{3,24}$)[a-zA-Z](?!.*--)[a-zA-Z0-9-]*[a-zA-Z0-9]$", - "validationMessage": "[if(or(greater(length(steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultName), 24), less(length(steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultName), 3)),'Vault name must be between 3-24 alphanumeric characters. The name must begin with a letter, end with a letter or digit, and not contain consecutive hyphens.','Vault name must only contain alphanumeric characters and dashes and cannot start with a number')]" + "minAddressPrefixSize": "/24" + }, + "options": { + "hideExisting": false + }, + "subnets": { + "gatewaySubnet": { + "label": "Subnet", + "defaultValue": { + "name": "wls-aks-gateway-subnet", + "addressPrefixSize": "/24" + }, + "constraints": { + "minAddressPrefixSize": "/24", + "minAddressCount": 250, + "requireContiguousAddresses": false + } + } + }, + "visible": true + }, + { + "name": "appgwUsePrivateIP", + "type": "Microsoft.Common.CheckBox", + "label": "Configure frontend IP with private IP address", + "toolTip": "If checked, expose WebLogic Server with private IP address.", + "visible": false + }, + { + "name": "sslCertText00", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "Choose an option for providing the TLS/SSL certificate:" } }, { - "name": "keyVaultCustomIdentityKeyStoreDataSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the Identity KeyStore Data", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." + "name": "sslCertText01", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "    ⁃ Upload a TLS/SSL certificate: Upload the pre-signed certificate now." } }, { - "name": "keyVaultCustomIdentityKeyStorePassPhraseSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the passphrase for the Identity KeyStore", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." + "name": "sslCertText02", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "    ⁃ Generate a self-signed front-end certificate: Generate a self-signed front-end certificate and apply it during deployment.", + "link": { + "label": "Learn more", + "uri": "https://aka.ms/wls-aks-application-gateway-ssl-key-vault" + } } }, { - "name": "keyVaultCustomIdentityKeyStoreType", - "type": "Microsoft.Common.DropDown", - "visible": "true", - "label": "The Identity KeyStore type (JKS,PKCS12)", - "defaultValue": "JKS", - "toolTip": "One of the supported KeyStore types", + "name": "certificateOption", + "type": "Microsoft.Common.OptionsGroup", + "label": "Select desired TLS/SSL certificate option", + "defaultValue": "Generate a self-signed front-end certificate", + "toolTip": "Select desired TLS/SSL certificate option", "constraints": { "allowedValues": [ { - "label": "JKS", - "value": "JKS" + "label": "Generate a self-signed front-end certificate", + "value": "generateCert" }, { - "label": "PKCS12", - "value": "PKCS12" + "label": "Upload a TLS/SSL certificate", + "value": "haveCert" } ], "required": true - } + }, + "visible": true }, { - "name": "keyVaultPrivateKeyAliasSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the Private Key Alias", - "defaultValue": "", - "toolTip": "Use only letters and numbers", + "name": "appGatewaySSLCertData", + "type": "Microsoft.Common.FileUpload", + "label": "Front-End TLS/SSL certificate(.pfx)", + "toolTip": "TLS/SSL certificate used for App Gateway", "constraints": { "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } + "accept": ".pfx" + }, + "options": { + "multiple": false, + "uploadMode": "file", + "openMode": "binary" + }, + "visible": "[equals(steps('section_appGateway').appgwIngress.certificateOption, 'haveCert')]" }, { - "name": "keyVaultPrivateKeyPassPhraseSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the passphrase for the Private Key", - "defaultValue": "", - "toolTip": "Use only letters and numbers", + "name": "appGatewaySSLCertPassword", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Password", + "confirmPassword": "Confirm password" + }, + "toolTip": "Front-End TLS/SSL certificate password", "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } + "required": "[equals(steps('section_appGateway').appgwIngress.certificateOption, 'haveCert')]", + "regex": "^((?=.*[0-9])(?=.*[a-z])|(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])|(?=.*[0-9])(?=.*[a-z])(?=.*[!@#$%^&*])|(?=.*[0-9])(?=.*[A-Z])(?=.*[!@#$%^&*])|(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*])).{6,128}$", + "validationMessage": "The password must contain at least 6 characters, with at least 1 uppercase letter, 1 lowercase letter and 1 number." + }, + "options": { + "hideConfirmation": false + }, + "visible": "[equals(steps('section_appGateway').appgwIngress.certificateOption, 'haveCert')]" }, { - "name": "keyVaultCustomTrustKeyStoreDataSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the Trust KeyStore Data", - "defaultValue": "", - "toolTip": "Use only letters and numbers", + "name": "uploadedSSLCertData", + "type": "Microsoft.Common.FileUpload", + "label": "Trusted root certificate(.cer, .cert)", + "toolTip": "Trusted root certificate (CA certificate) used to set up end to end TLS/SSL", "constraints": { "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } + "accept": ".cer, .cert" + }, + "options": { + "multiple": false, + "uploadMode": "file", + "openMode": "binary" + }, + "visible": "[steps('section_sslConfiguration').enableCustomSSL]" }, { - "name": "keyVaultCustomTrustKeyStorePassPhraseSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the passphrase for the Trust KeyStore", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } + "name": "enableCookieBasedAffinity", + "type": "Microsoft.Common.CheckBox", + "label": "Disable cookie based affinity", + "toolTip": "If checked, disable cookie based affinity", + "visible": true }, { - "name": "keyVaultCustomTrustKeyStoreType", - "type": "Microsoft.Common.DropDown", - "visible": "true", - "label": "The Trust KeyStore type (JKS,PKCS12)", - "defaultValue": "JKS", - "toolTip": "One of the supported KeyStore types", + "name": "appgwForAdminServer", + "type": "Microsoft.Common.OptionsGroup", + "label": "Create ingress for Administration Console. Make sure no application with path /console*, it will cause conflict with Administration Console path.", + "defaultValue": "No", + "toolTip": "Select 'Yes' to Create ingress for Administration Console. Make sure no application with path /console*, it will cause conflict with Administration Console path.", "constraints": { "allowedValues": [ { - "label": "JKS", - "value": "JKS" + "label": "Yes", + "value": true }, { - "label": "PKCS12", - "value": "PKCS12" + "label": "No", + "value": false } - ], - "required": true - } - } - ] - } - ] - }, - { - "name": "section_appGateway", - "type": "Microsoft.Common.Section", - "label": "Networking", - "subLabel": { - "preValidation": "Provide required information for networking", - "postValidation": "Done" - }, - "bladeTitle": "Networking", - "elements": [ - { - "name": "connectToAGText", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "Selecting 'Yes' here will cause the template to provision Load Balancer service or Ingress service for WebLogic Administration Console and WebLogic cluster.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-cluster-app-gateway-overview" - } - } - }, - { - "name": "lbSVCInfo", - "type": "Microsoft.Common.Section", - "label": "Standard Load Balancer service", - "elements": [ + ] + }, + "visible": true + }, { - "name": "enableLBSVC", + "name": "appgwForAdminRemote", "type": "Microsoft.Common.OptionsGroup", - "label": "Create Standard Load Balancer services for the cluster?", + "label": "Create ingress for WebLogic Remote Console. Make sure no application with path /remoteconsole*, it will cause conflict with WebLogic Remote Console path.", "defaultValue": "No", - "toolTip": "Select 'Yes' to create Standard Load Balancer services for the cluster.", + "toolTip": "Select 'Yes' to Create ingress for WebLogic Remote Console. Make sure no application with path /remoteconsole*, it will cause conflict with WebLogic Remote Console path.", "constraints": { "allowedValues": [ { @@ -976,28 +1308,71 @@ "label": "No", "value": false } - ], - "required": false + ] + }, + "visible": true + } + ], + "visible": "[equals(steps('section_appGateway').loadBalancingOptions, 'agic')]" + }, + { + "name": "lbSVCInfo", + "type": "Microsoft.Common.Section", + "label": "Standard Load Balancer Service", + "elements": [ + { + "name": "enableLBSVCText", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "This option will cause the offer to provision the Azure Load Balancer service to expose the WebLogic Server Administration Console and the cluster.", + "link": { + "label": "Learn more", + "uri": "https://aka.ms/wls-aks-standard-load-balancer" + } + } + }, + { + "name": "enableInternalLBText", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "If checked, the offer will configure the load balancer as an internal load balancer.", + "link": { + "label": "Learn more", + "uri": "https://aka.ms/wls-aks-internal-load-balancer" + } } }, { "name": "enableInternalLB", "type": "Microsoft.Common.CheckBox", "label": "Use Internal Load Balancer", - "visible": "[steps('section_appGateway').lbSVCInfo.enableLBSVC]" + "toolTip": "If checked, the offer will configure the load balancer as an internal load balancer.", + "visible": true + }, + { + "name": "infoBoxForLbSvc", + "type": "Microsoft.Common.InfoBox", + "visible": true, + "options": { + "icon": "info", + "text": "There must be at least one and at most two entries." + } }, { "name": "lbSVC", "type": "Microsoft.Common.EditableGrid", "ariaLabel": "Enter information", "label": "Standard Load Balancer service", - "visible": "[steps('section_appGateway').lbSVCInfo.enableLBSVC]", + "toolTip": "Create Azure Standard Load Balancer service for Administration Console and cluster.", + "visible": true, "constraints": { "width": "Full", "rows": { "count": { - "min": 0, - "max": 4 + "min": 1, + "max": 2 } }, "columns": [ @@ -1007,7 +1382,8 @@ "width": "2fr", "element": { "type": "Microsoft.Common.TextBox", - "placeholder": "domain1-admin-server", + "placeholder": "Input a prefix...", + "toolTip": "Input a prefix for service name. For example, inputing 'domain1-admin-server' will cause provisioning a Load Balancer service named with 'domain1-admin-server*' and exposing the Oracle WebLogic Administration Server to Internet.", "constraints": { "required": true, "validations": [ @@ -1021,346 +1397,73 @@ } ] } - } - }, - { - "id": "colTarget", - "header": "Target", - "width": "2fr", - "element": { - "name": "dropDownTargets", - "type": "Microsoft.Common.DropDown", - "placeholder": "admin-server", - "constraints": { - "allowedValues": [ - { - "label": "admin-server", - "value": "adminServer" - }, - { - "label": "admin-server-t3", - "value": "adminServerT3" - }, - { - "label": "cluster-1", - "value": "cluster1" - }, - { - "label": "cluster-1-t3", - "value": "cluster1T3" - } - ], - "required": true - } - } - }, - { - "id": "colPort", - "header": "Port", - "width": "1fr", - "element": { - "type": "Microsoft.Common.TextBox", - "placeholder": "7001", - "constraints": { - "required": true, - "validations": [ - { - "isValid": "[lessOrEquals(length(filter(steps('section_appGateway').lbSVCInfo.lbSVC, (item) => equals(item.colTarget, last(take(steps('section_appGateway').lbSVCInfo.lbSVC, $rowIndex)).colTarget))),1)]", - "message": "You can not select the same target repeadly." - }, - { - "regex": "^()([1-9]|[1-5]?[0-9]{2,4}|6[1-4][0-9]{3}|65[1-4][0-9]{2}|655[1-2][0-9]|6553[1-5])$", - "message": "Only numbers are allowed, and the value must be 1-65535." - } - ] - } - } - } - ] - } - } - ], - "visible": true - }, - { - "name": "appgwIngress", - "type": "Microsoft.Common.Section", - "label": "Application Gateway Ingress", - "elements": [ - { - "name": "enableAppGateway", - "type": "Microsoft.Common.OptionsGroup", - "label": "Connect to Azure Application Gateway?", - "defaultValue": "No", - "toolTip": "Select 'Yes' to create an Azure Application Gateway Ingress as the load balancer for the cluster and admin server.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": true - }, - { - "label": "No", - "value": false - } - ], - "required": false - } - }, - { - "name": "keyVaultText00", - "type": "Microsoft.Common.TextBlock", - "visible": "[steps('section_appGateway').appgwIngress.enableAppGateway]", - "options": { - "text": "Choose an option for providing the TLS/SSL certificate:" - } - }, - { - "name": "keyVaultText01", - "type": "Microsoft.Common.TextBlock", - "visible": "[steps('section_appGateway').appgwIngress.enableAppGateway]", - "options": { - "text": "    ⁃ Upload a TLS/SSL certificate: Upload the pre-signed certificate now." - } - }, - { - "name": "keyVaultText02", - "type": "Microsoft.Common.TextBlock", - "visible": "[steps('section_appGateway').appgwIngress.enableAppGateway]", - "options": { - "text": "    ⁃ Identify an Azure Key Vault: The Key Vault must already contain the certificate and its password stored as secrets." - } - }, - { - "name": "keyVaultText03", - "type": "Microsoft.Common.TextBlock", - "visible": "[steps('section_appGateway').appgwIngress.enableAppGateway]", - "options": { - "text": "    ⁃ Generate a self-signed frontend certificate: generate a self-signed frontend certificate and apply it during deployment.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-cluster-app-gateway-key-vault" - } - } - }, - { - "name": "certificateOption", - "type": "Microsoft.Common.OptionsGroup", - "label": "Select desired TLS/SSL certificate option", - "defaultValue": "Upload a TLS/SSL certificate", - "toolTip": "Select desired TLS/SSL certificate option", - "constraints": { - "allowedValues": [ - { - "label": "Upload a TLS/SSL certificate", - "value": "haveCert" - }, - { - "label": "Identify an Azure Key Vault", - "value": "haveKeyVault" - }, - { - "label": "Generate a self-signed frontend certificate", - "value": "generateCert" - } - ], - "required": true - }, - "visible": "[steps('section_appGateway').appgwIngress.enableAppGateway]" - }, - { - "name": "keyVaultSSLCertData", - "type": "Microsoft.Common.FileUpload", - "label": "Frontend TLS/SSL certificate(.pfx)", - "toolTip": "TLS/SSL certificate used for App Gateway", - "constraints": { - "required": true, - "accept": ".pfx" - }, - "options": { - "multiple": false, - "uploadMode": "file", - "openMode": "binary" - }, - "visible": "[equals(steps('section_appGateway').appgwIngress.certificateOption, 'haveCert')]" - }, - { - "name": "appGatewaySSLCertPassword", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Password", - "confirmPassword": "Confirm password" - }, - "toolTip": "Frontend TLS/SSL certificate password", - "constraints": { - "required": "[equals(steps('section_appGateway').appgwIngress.certificateOption, 'haveCert')]", - "regex": "^((?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*])).{6,128}$", - "validationMessage": "The password must contain at least 6 characters, with at least 1 uppercase letter, 1 lowercase letter and 1 number." - }, - "options": { - "hideConfirmation": false - }, - "visible": "[equals(steps('section_appGateway').appgwIngress.certificateOption, 'haveCert')]" - }, - { - "name": "keyVaultBackendSSLCertData", - "type": "Microsoft.Common.FileUpload", - "label": "Trusted root certificate(.cer, .cert)", - "toolTip": "Trusted root certificate (CA certificate) used to set up end to end TLS/SSL", - "constraints": { - "required": true, - "accept": ".cer, .cert" - }, - "options": { - "multiple": false, - "uploadMode": "file", - "openMode": "binary" - }, - "visible": "[and(steps('section_appGateway').appgwIngress.enableAppGateway, steps('section_sslConfiguration').enableCustomSSL, not(equals(steps('section_appGateway').appgwIngress.certificateOption, 'haveKeyVault')))]" - }, - { - "name": "keyVaultResourceGroup", - "type": "Microsoft.Common.TextBox", - "label": "Resource group name in current subscription containing the Key Vault", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1})$", - "validationMessage": "[if(greater(length(steps('section_appGateway').appgwIngress.keyVaultResourceGroup), 90),'Resource group names only allow up to 90 characters.', 'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" - }, - "visible": "[equals(steps('section_appGateway').appgwIngress.certificateOption, 'haveKeyVault')]" - }, - { - "name": "keyVaultName", - "type": "Microsoft.Common.TextBox", - "label": "Name of the Azure Key Vault containing secrets for the certificate for TLS/SSL Termination", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^(?=.{3,24}$)[a-zA-Z](?!.*--)[a-zA-Z0-9-]*[a-zA-Z0-9]$", - "validationMessage": "[if(or(greater(length(steps('section_appGateway').appgwIngress.keyVaultName), 24), less(length(steps('section_appGateway').appgwIngress.keyVaultName), 3)),'Vault name must be between 3-24 alphanumeric characters. The name must begin with a letter, end with a letter or digit, and not contain consecutive hyphens.','Vault name must only contain alphanumeric characters and dashes and cannot start with a number')]" - }, - "visible": "[equals(steps('section_appGateway').appgwIngress.certificateOption, 'haveKeyVault')]" - }, - { - "name": "keyVaultSSLCertDataSecretName", - "type": "Microsoft.Common.TextBox", - "label": "The name of the secret in the specified Key Vault whose value is the frontend TLS/SSL certificate data", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - }, - "visible": "[equals(steps('section_appGateway').appgwIngress.certificateOption, 'haveKeyVault')]" - }, - { - "name": "keyVaultSSLCertPasswordSecretName", - "type": "Microsoft.Common.TextBox", - "label": "The name of the secret in the specified Key Vault whose value is the password for the frontend TLS/SSL certificate", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - }, - "visible": "[equals(steps('section_appGateway').appgwIngress.certificateOption, 'haveKeyVault')]" - }, - { - "name": "keyVaultBackendSSLCertDataSecretName", - "type": "Microsoft.Common.TextBox", - "label": "The name of the secret in the specified Key Vault whose value is the trusted root certificate data", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - }, - "visible": "[and(steps('section_sslConfiguration').enableCustomSSL, equals(steps('section_appGateway').appgwIngress.certificateOption, 'haveKeyVault'))]" - }, - { - "name": "servicePrincipal", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Service Principal", - "confirmPassword": "Confirm password" - }, - "toolTip": "Base64 encoded JSON blob of the service principal. You can generate one with command 'az ad sp create-for-rbac --sdk-auth | base64 -w0'", - "constraints": { - "required": true - }, - "options": { - "hideConfirmation": true - }, - "visible": "[steps('section_appGateway').appgwIngress.enableAppGateway]" - }, - { - "name": "enableCookieBasedAffinity", - "type": "Microsoft.Common.CheckBox", - "label": "Enable cookie based affinity", - "visible": "[steps('section_appGateway').appgwIngress.enableAppGateway]" - }, - { - "name": "appgwForAdminServer", - "type": "Microsoft.Common.OptionsGroup", - "label": "Create ingress for Administration Console. Make sure no application with path /console*, it will cause conflict with Administration Console path.", - "defaultValue": "Yes", - "toolTip": "Select 'Yes' to Create ingress for Administration Console. Make sure no application with path /console*, it will cause conflict with Administration Console path.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": true + } }, { - "label": "No", - "value": false - } - ] - }, - "visible": "[steps('section_appGateway').appgwIngress.enableAppGateway]" - }, - { - "name": "appgwForAdminRemote", - "type": "Microsoft.Common.OptionsGroup", - "label": "Create ingress for WebLogic Remote Console. Make sure no application with path /remoteconsole*, it will cause conflict with WebLogic Remote Console path.", - "defaultValue": "Yes", - "toolTip": "Select 'Yes' to Create ingress for WebLogic Remote Console. Make sure no application with path /remoteconsole*, it will cause conflict with WebLogic Remote Console path.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": true + "id": "colTarget", + "header": "Target", + "width": "2fr", + "element": { + "type": "Microsoft.Common.DropDown", + "placeholder": "Select a target...", + "toolTip": "Create Azure Standard Load Balancer Servicer for the selected target.", + "constraints": { + "allowedValues": [ + { + "label": "admin-server", + "value": "adminServer" + }, + { + "label": "cluster-1", + "value": "cluster1" + } + ], + "required": true + } + } }, { - "label": "No", - "value": false + "id": "colPort", + "header": "Port", + "width": "1fr", + "element": { + "type": "Microsoft.Common.TextBox", + "placeholder": "Input a port...", + "toolTip": "Public port for the target service, it's suggested to use 7001 for Oracle WebLogic Administration Server, and 8001 for cluster.", + "constraints": { + "required": true, + "validations": [ + { + "isValid": "[lessOrEquals(length(filter(steps('section_appGateway').lbSVCInfo.lbSVC, (item) => equals(item.colTarget, last(take(steps('section_appGateway').lbSVCInfo.lbSVC, $rowIndex)).colTarget))),1)]", + "message": "You can not select the same target repeatedly." + }, + { + "regex": "^()([1-9]|[1-5]?[0-9]{2,4}|6[1-4][0-9]{3}|65[1-4][0-9]{2}|655[1-2][0-9]|6553[1-5])$", + "message": "Only numbers are allowed, and the value must be 1-65535." + } + ] + } + } } ] - }, - "visible": "[steps('section_appGateway').appgwIngress.enableAppGateway]" + } } ], - "visible": true + "visible": "[equals(steps('section_appGateway').loadBalancingOptions, 'lbservice')]" } ] }, { "name": "section_dnsConfiguration", "type": "Microsoft.Common.Section", - "label": "DNS Configuration", + "label": "DNS", "elements": [ { "name": "dnsConfigurationText", "type": "Microsoft.Common.TextBlock", "visible": true, "options": { - "text": "Selecting 'Yes' here will cause the template to provision Oracle WebLogic Server Administration Console, cluster, Remote Console and custom T3 channel using custom DNS Name (example: admin.contoso.com)", + "text": "Selecting 'Yes' here will cause the offer to provision Oracle WebLogic Server Administration Console, cluster, and Remote Console using custom DNS Name (example: admin.contoso.com)", "link": { "label": "Learn more", "uri": "https://aka.ms/arm-oraclelinux-wls-dns" @@ -1370,7 +1473,7 @@ { "name": "enableDNSConfiguration", "type": "Microsoft.Common.OptionsGroup", - "label": "Configure Custom DNS Alias", + "label": "Custom DNS Alias", "defaultValue": "No", "toolTip": "Select 'Yes' to configure Custom DNS Alias.", "constraints": { @@ -1428,7 +1531,7 @@ "toolTip": "Name of the resource group which contains the DNS Zone in current subscription", "constraints": { "required": true, - "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1})$", + "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1}){3,63}$", "validationMessage": "[if(greater(length(steps('section_dnsConfiguration').dnsZoneResourceGroup), 90),'Resource group names only allow up to 90 characters.', 'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" }, "visible": "[and(steps('section_dnsConfiguration').enableDNSConfiguration,steps('section_dnsConfiguration').bringDNSZone)]" @@ -1436,9 +1539,9 @@ { "name": "dnszoneAdminConsoleLabel", "type": "Microsoft.Common.TextBox", - "label": "Label for Oracle WebLogic Administration Console", + "label": "Label for Oracle WebLogic Server Administration Console", "defaultValue": "admin", - "toolTip": "Specify a label to generate subdomain of Oracle WebLogic Administration Console", + "toolTip": "Specify a label to generate subdomain of Oracle WebLogic Server Administration Console", "constraints": { "required": true, "validations": [ @@ -1452,14 +1555,14 @@ } ] }, - "visible": "[steps('section_dnsConfiguration').enableDNSConfiguration]" + "visible": "[and(steps('section_dnsConfiguration').enableDNSConfiguration, not(equals(steps('section_appGateway').loadBalancingOptions,'none')))]" }, { "name": "dnszoneAdminT3ChannelLabel", "type": "Microsoft.Common.TextBox", - "label": "Label for Oracle WebLogic Admin Server T3 channel", + "label": "Label for Oracle WebLogic Administration Server T3 channel", "defaultValue": "admin-t3", - "toolTip": "Specify a label to generate subdomain of Oracle WebLogic Admin Server T3 channel", + "toolTip": "Specify a label to generate subdomain of Oracle WebLogic Administration Server T3 channel", "constraints": { "required": true, "validations": [ @@ -1473,7 +1576,7 @@ } ] }, - "visible": "[and(steps('section_dnsConfiguration').enableDNSConfiguration,basics('basicsOptional').enableAdminT3Tunneling, steps('section_appGateway').lbSVCInfo.enableLBSVC)]" + "visible": "[and(steps('section_dnsConfiguration').enableDNSConfiguration,basics('basicsOptional').enableAdminT3Tunneling, equals(steps('section_appGateway').loadBalancingOptions,'lbservice'))]" }, { "name": "dnszoneGatewayLabel", @@ -1494,7 +1597,7 @@ } ] }, - "visible": "[steps('section_dnsConfiguration').enableDNSConfiguration]" + "visible": "[and(steps('section_dnsConfiguration').enableDNSConfiguration, not(equals(steps('section_appGateway').loadBalancingOptions,'none')))]" }, { "name": "dnszoneClusterT3ChannelLabel", @@ -1515,7 +1618,7 @@ } ] }, - "visible": "[and(steps('section_dnsConfiguration').enableDNSConfiguration,basics('basicsOptional').enableClusterT3Tunneling, steps('section_appGateway').lbSVCInfo.enableLBSVC)]" + "visible": "[and(steps('section_dnsConfiguration').enableDNSConfiguration,basics('basicsOptional').enableClusterT3Tunneling, equals(steps('section_appGateway').loadBalancingOptions,'lbservice'))]" } ] }, @@ -1534,7 +1637,7 @@ "type": "Microsoft.Common.TextBlock", "visible": true, "options": { - "text": "Selecting 'Yes' here and providing the configuration will cause the template to configure the WebLogic Server to connect to the desired pre-existing database. The database must be network accessible to the VNET and subnets created by the template." + "text": "Selecting 'Yes' here and providing the configuration will cause the offer to configure the WebLogic Server to connect to the desired pre-existing database. The database must be network accessible to the VNET and subnets created by the offer." } }, { @@ -1571,7 +1674,7 @@ "constraints": { "allowedValues": [ { - "label": "Azure database for PostgreSQL", + "label": "PostgreSQL (Supports passwordless connection)", "value": "postgresql" }, { @@ -1579,14 +1682,31 @@ "value": "oracle" }, { - "label": "Azure SQL", + "label": "Microsoft SQL Server (Supports passwordless connection)", "value": "sqlserver" + }, + { + "label": "MySQL (Supports passwordless connection)", + "value": "mysql" + }, + { + "label": "Other", + "value": "otherdb" } ], "required": true }, "visible": true }, + { + "name": "mysqlJDBCDriverInfo", + "type": "Microsoft.Common.InfoBox", + "visible": "[and(bool(steps('section_database').enableDB),equals(steps('section_database').databaseConnectionInfo.databaseType, 'mysql'))]", + "options": { + "icon": "Info", + "text": "To support passwordless connection and various functionalities, the offer will upgrade the
    Oracle WebLogic Server MySQL driver with recent MySQL Connector Java driver." + } + }, { "name": "jdbcDataSourceName", "type": "Microsoft.Common.TextBox", @@ -1594,7 +1714,7 @@ "toolTip": "The JNDI name for the database JDBC connection", "defaultValue": "", "constraints": { - "required": "[bool(steps('section_database').enableDB)]", + "required": true, "regex": "^[a-zA-Z0-9./_-]{1,30}$", "validationMessage": "The value must be 1-30 characters long and must only contain letters, numbers, hyphens (-), underscores (_), periods (.) and slashes (/)." }, @@ -1607,12 +1727,91 @@ "toolTip": "The JDBC connection string for the database", "defaultValue": "", "constraints": { - "required": "[bool(steps('section_database').enableDB)]", - "regex": "[concat('^jdbc:', coalesce(steps('section_database').databaseConnectionInfo.databaseType, ''), '.*$')]", + "required": true, + "validations": [ + { + "regex": "^jdbc:.*$", + "message": "A valid JDBC URL must start with 'jdbc:'." + }, + { + "isValid": "[startsWith(steps('section_database').databaseConnectionInfo.dsConnectionURL, concat('jdbc:', steps('section_database').databaseConnectionInfo.databaseType))]", + "message": "A valid JDBC URL for the chosen database type must be provided." + }, + { + "isValid": "[if(and(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection), equals(steps('section_database').databaseConnectionInfo.databaseType, 'mysql')), and(not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'defaultAuthenticationPlugin')),not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'authenticationPlugins')), not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'azure.clientId'))), 'true')]", + "message": "The offer will append defaultAuthenticationPlugin, authenticationPlugins with Azure provided plugins, and append azure.clientId with your managed identity client ID automatically, please do not specify them in your connection string." + }, + { + "isValid": "[if(and(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection), equals(steps('section_database').databaseConnectionInfo.databaseType, 'postgresql')), and(not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'authenticationPluginClassName')),not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'azure.clientId'))), 'true')]", + "message": "The offer will append authenticationPluginClassName with Azure provided plugins, and append azure.clientId with your managed identity client ID automatically, please do not specify them in your connection string." + }, + { + "isValid": "[if(and(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection0),equals(steps('section_database').databaseConnectionInfo.databaseType, 'sqlserver')), greater(length(steps('section_database').databaseConnectionInfo.dbIdentity.userAssignedIdentities),0), bool('true'))]", + "message": "You must select at least one managed identity that has access to your database." + } + ] + }, + "visible": "[and(bool(steps('section_database').enableDB), not(equals(steps('section_database').databaseConnectionInfo.databaseType, 'otherdb')))]" + }, + { + "name": "dsConnectionURL2", + "type": "Microsoft.Common.TextBox", + "label": "DataSource Connection String", + "toolTip": "The JDBC connection string for the database", + "defaultValue": "", + "constraints": { + "required": true, + "regex": "^jdbc:.*$", "validationMessage": "A valid JDBC URL for the chosen database type must be provided" }, + "visible": "[and(bool(steps('section_database').enableDB), equals(steps('section_database').databaseConnectionInfo.databaseType, 'otherdb'))]" + }, + { + "name": "dbGlobalTranPro", + "type": "Microsoft.Common.DropDown", + "label": "Global transactions protocol", + "defaultValue": "OnePhaseCommit", + "multiLine": true, + "toolTip": "Determines the transaction protocol (global transaction processing behavior) for the data source.", + "constraints": { + "allowedValues": [ + { + "label": "TwoPhaseCommit", + "description": "Standard XA transaction processing. Requires an XA driver.", + "value": "TwoPhaseCommit" + }, + { + "label": "LoggingLastResource", + "description": "A performance enhancement for one non-XA resource.", + "value": "LoggingLastResource" + }, + { + "label": "EmulateTwoPhaseCommit", + "description": "Enables one non-XA resource to participate in a global transaction, but has some risk to data.", + "value": "EmulateTwoPhaseCommit" + }, + { + "label": "OnePhaseCommit", + "description": "One-phase XA transaction processing using a non-XA driver. This is the default setting.", + "value": "OnePhaseCommit" + }, + { + "label": "None", + "description": "Support for local transactions only.", + "value": "None" + } + ], + "required": true + }, "visible": true }, + { + "name": "enablePswlessConnection0", + "type": "Microsoft.Common.CheckBox", + "label": "Use passwordless datasource connection", + "toolTip": "Use passwordless datasource connection.", + "visible": "[and(bool(steps('section_database').enableDB),equals(steps('section_database').databaseConnectionInfo.databaseType, 'sqlserver'))]" + }, { "name": "dbUser", "type": "Microsoft.Common.TextBox", @@ -1620,11 +1819,26 @@ "toolTip": "Use only letters and numbers", "defaultValue": "", "constraints": { - "required": "[bool(steps('section_database').enableDB)]", - "regex": "^(?=.{1,128}$)[a-zA-Z](?!.*--)(?!.*@@)(?!.*-@)(?!.*@-)[a-zA-Z0-9-@]*[a-zA-Z0-9]$", - "validationMessage": "The value must be 1-128 characters long and must only contain letters, numbers, hyphen(-) and the at sign, no hyphen allowed at the beginning and the end of database username." + "required": true, + "validations": [ + { + "regex": "^(?=.{1,128}$)[a-zA-Z](?!.*--)(?!.*@@)(?!.*-@)(?!.*@-)[a-zA-Z0-9-@]*[a-zA-Z0-9]$", + "message": "The value must be 1-128 characters long and must only contain letters, numbers, hyphen(-) and the at sign, no hyphen allowed at the beginning and the end of database username." + }, + { + "isValid": "[if(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection), greater(length(steps('section_database').databaseConnectionInfo.dbIdentity.userAssignedIdentities),0), bool('true'))]", + "message": "You must select at least one managed identity that has access to your database." + } + ] }, - "visible": true + "visible": "[and(bool(steps('section_database').enableDB), not(and(steps('section_database').databaseConnectionInfo.enablePswlessConnection0, equals(steps('section_database').databaseConnectionInfo.databaseType, 'sqlserver'))))]" + }, + { + "name": "enablePswlessConnection", + "type": "Microsoft.Common.CheckBox", + "label": "Use passwordless datasource connection", + "toolTip": "Use passwordless datasource connection.", + "visible": "[and(bool(steps('section_database').enableDB),or(equals(steps('section_database').databaseConnectionInfo.databaseType, 'mysql'),equals(steps('section_database').databaseConnectionInfo.databaseType, 'postgresql')))]" }, { "name": "dbPassword", @@ -1635,38 +1849,284 @@ }, "toolTip": "Database Password", "constraints": { - "required": "[bool(steps('section_database').enableDB)]", - "regex": "^((?=.*[0-9])(?=.*[a-zA-Z!@#$%^&*])).{5,128}$", - "validationMessage": "The password must be between 5 and 128 characters long and have at least one number." + "required": true, + "regex": "^((?=.*[0-9])(?=.*[a-zA-Z!@#$%^&*])).{6,128}$", + "validationMessage": "The password must be between 6 and 128 characters long and have at least one number." }, "options": { "hideConfirmation": false }, - "visible": true + "visible": "[and(bool(steps('section_database').enableDB), not(or(steps('section_database').databaseConnectionInfo.enablePswlessConnection, steps('section_database').databaseConnectionInfo.enablePswlessConnection0)))]" + }, + { + "name": "dbIdentity", + "type": "Microsoft.ManagedIdentity.IdentitySelector", + "label": "Connect database with Managed Identity", + "toolTip": { + "userAssignedIdentity": "Select a user assigned identity that has access to your database. For how to create a database user for your managed identity, see https://aka.ms/javaee-db-identity." + }, + "defaultValue": { + "systemAssignedIdentity": "Off" + }, + "options": { + "hideSystemAssignedIdentity": true, + "hideUserAssignedIdentity": false + }, + "visible": "[and(bool(steps('section_database').enableDB), or(steps('section_database').databaseConnectionInfo.enablePswlessConnection, steps('section_database').databaseConnectionInfo.enablePswlessConnection0))]" + }, + { + "name": "dbDriverLibraries", + "type": "Microsoft.Common.FileUpload", + "label": "DataSource driver (.jar)", + "toolTip": "The datasource driver jar package for the specified database.", + "constraints": { + "required": true, + "accept": ".jar" + }, + "options": { + "multiple": true, + "uploadMode": "url", + "openMode": "binary" + }, + "visible": "[and(bool(steps('section_database').enableDB), equals(steps('section_database').databaseConnectionInfo.databaseType, 'otherdb'))]" + }, + { + "name": "dbDriverInfoBox", + "type": "Microsoft.Common.InfoBox", + "options": { + "icon": "Info", + "text": "WebLogic Server provides support for application data access to any database using a JDBC-compliant driver.
    Select here for more details.", + "uri": "https://aka.ms/wls-aks-dbdriver" + }, + "visible": "[and(bool(steps('section_database').enableDB), equals(steps('section_database').databaseConnectionInfo.databaseType, 'otherdb'))]" + }, + { + "name": "dbDriverName", + "type": "Microsoft.Common.TextBox", + "label": "DataSource driver name", + "toolTip": "The driver name for the database", + "placeholder": "com.informix.jdbc.IfxDriver", + "constraints": { + "required": true, + "regex": "^[a-zA-Z_][a-zA-Z0-9_]+(\\.[a-zA-Z_][a-zA-Z0-9_]+){1,50}$", + "validationMessage": "A valid driver name for the chosen database type must be provided" + }, + "visible": "[and(bool(steps('section_database').enableDB), equals(steps('section_database').databaseConnectionInfo.databaseType, 'otherdb'))]" + }, + { + "name": "dbTestTableName", + "type": "Microsoft.Common.TextBox", + "label": "Test table name", + "toolTip": "The name of the database table to use when testing physical database connections. ", + "constraints": { + "required": true, + "regex": "^.*$", + "validationMessage": "A test table name for the chosen database type must be provided" + }, + "visible": "[and(bool(steps('section_database').enableDB), equals(steps('section_database').databaseConnectionInfo.databaseType, 'otherdb'))]" } ], "visible": "[bool(steps('section_database').enableDB)]" } ] + }, + { + "name": "section_autoScaling", + "type": "Microsoft.Common.Section", + "label": "Autoscaling", + "subLabel": { + "preValidation": "Configure Horizontal Autoscaling", + "postValidation": "Done" + }, + "bladeTitle": "Horizontal Autoscaling", + "elements": [ + { + "name": "aboutAutoscaling", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "Selecting 'Yes' here and providing the configuration will cause the offer configure metric to scale the WebLogic cluster." + } + }, + { + "name": "enableAutoscaling", + "type": "Microsoft.Common.OptionsGroup", + "label": "Provision resources for horizontal autoscaling?", + "defaultValue": "No", + "toolTip": "Select 'Yes' and provide required info to configure horizontal autoscaling.", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": "true" + }, + { + "label": "No", + "value": "false" + } + ], + "required": true + } + }, + { + "name": "autoScalingInfo", + "type": "Microsoft.Common.Section", + "label": "Horizontal autoscaling settings", + "elements": [ + { + "name": "metricSource", + "type": "Microsoft.Common.OptionsGroup", + "label": "Select autoscaling option. ", + "defaultValue": "Kubernetes Metrics Server (simple autoscaling)", + "toolTip": "If you select Kubernetes Metrics Server, this offer configures WebLogic Server to scale based on CPU or memory utilization. If you select WebLogic Monitoring Exporter, this offer configures WebLogic Monitoring Exporter to scrape WebLogic Server metrics and feed them to Azure Monitor Managed Service for Prometheus; integrates KEDA with your AKS cluster to monitor Azure Monitor workspace and feed data to AKS. You can create KEDA scaler based on Java metrics from Azure Monitor workspace", + "constraints": { + "allowedValues": [ + { + "label": "Kubernetes Metrics Server (simple autoscaling)", + "value": "kms" + }, + { + "label": "WebLogic Monitoring Exporter (advanced autoscaling)", + "value": "wme" + } + ], + "required": true + }, + "visible": true + }, + { + "name": "infoKms", + "type": "Microsoft.Common.InfoBox", + "visible": "[equals(steps('section_autoScaling').autoScalingInfo.metricSource, 'kms')]", + "options": { + "icon": "None", + "text": "This option configures and runs Kubernetes Horizontal Pod Autoscaler (HPA) to scale a WebLogic cluster, based on the CPU or memory utilization. The HPA autoscales WebLogic Server instances from a minimum of 1 cluster members up to maximum of cluster members, and the scale up or down action occur when the average CPU/memory is consistently over the utilization.
  • Default maximum of cluster member is 5. You can set it from Basics -> Optional Basic Configuration -> Maximum dynamic cluster size.
  • Default CPU request is 200m.
  • Default memory request is 1.5Gi.
  • ", + "uri": "https://aka.ms/wlsoperator-autoscaling-hpa" + } + }, + { + "name": "infoWme", + "type": "Microsoft.Common.InfoBox", + "visible": "[equals(steps('section_autoScaling').autoScalingInfo.metricSource, 'wme')]", + "options": { + "icon": "None", + "text": "This option installs all the software necessary to allow you to create Java metric aware KEDA scaling rules.
    The offer provisions the following deployments. Right-click and select Open Link in New Tab to follow links:
    After the provisioning is completed, you can create KEDA scaling rules. A sample rule is provided in the deployment outputs. The following steps show how to see the sample rule.
    • View the resource group for this deployment in the Azure portal.
    • In the Settings section, select Deployments.
    • Select the oldest deployment. The name of the deployment looks similar to oracle.20210620-wls-on-aks.
    • Select Outputs.
    • The shellCmdtoOutputKedaScalerSample value is the base64 string of a scaler sample. Copy the value and run it in your terminal.
    • For guidance on how to complete the configuration, see Tutorial: Migrate Oracle WebLogic Server to AKS with KEDA scaler based on Prometheus Metrics
    ", + "uri": "https://aka.ms/wls-aks-keda-scaler" + } + }, + { + "name": "kmsMetrics", + "type": "Microsoft.Common.OptionsGroup", + "label": "Select metric. ", + "defaultValue": "Average CPU Utilization", + "toolTip": "Select metric.", + "constraints": { + "allowedValues": [ + { + "label": "Average CPU Utilization", + "value": "cpu" + }, + { + "label": "Average Memory Utilization", + "value": "memory" + } + ], + "required": true + }, + "visible": "[equals(steps('section_autoScaling').autoScalingInfo.metricSource, 'kms')]" + }, + { + "name": "averageCpuUtilization", + "type": "Microsoft.Common.Slider", + "min": 10, + "max": 100, + "label": "Average CPU Utilization", + "subLabel": "Percent", + "defaultValue": 60, + "showStepMarkers": false, + "toolTip": "Pick Average CPU Utilization in Percent", + "constraints": { + "required": false + }, + "visible": "[equals(steps('section_autoScaling').autoScalingInfo.kmsMetrics, 'cpu')]" + }, + { + "name": "averageMemoryUtilization", + "type": "Microsoft.Common.Slider", + "min": 10, + "max": 100, + "label": "Average Memory Utilization", + "subLabel": "Percent", + "defaultValue": 60, + "showStepMarkers": false, + "toolTip": "Pick Average Memory Utilization in Percent", + "constraints": { + "required": false + }, + "visible": "[equals(steps('section_autoScaling').autoScalingInfo.kmsMetrics, 'memory')]" + } + ], + "visible": "[bool(steps('section_autoScaling').enableAutoscaling)]" + } + ] + }, + { + "name": "tags", + "label": "Tags", + "elements": [ + { + "name": "tagsByResource", + "type": "Microsoft.Common.TagsByResource", + "resources": [ + "${identifier.managedClusters}", + "${identifier.applicationGateways}", + "${identifier.registries}", + "${identifier.virtualMachines}", + "${identifier.virtualMachinesExtensions}", + "${identifier.virtualNetworks}", + "${identifier.networkInterfaces}", + "${identifier.networkSecurityGroups}", + "${identifier.publicIPAddresses}", + "${identifier.storageAccounts}", + "${identifier.vaults}", + "${identifier.userAssignedIdentities}", + "${identifier.dnszones}", + "${identifier.workspaces}", + "${identifier.accounts}", + "${identifier.deploymentScripts}" + ], + "toolTip": "Tags help you organize your resources and categorize them for billing or management purposes. You can apply tags to resources deployed by the offer." + } + ] } ], "outputs": { - "acrName": "[last(split(steps('section_aks').acrInfo.acrSelector.id, '/'))]", + "acrName": "[last(split(steps('section_aks').imageInfo.oracleAcrSelector.id, '/'))]", + "acrResourceGroupName": "[last(take(split(steps('section_aks').imageInfo.oracleAcrSelector.id, '/'),5))]", "aksAgentPoolNodeCount": "[steps('section_aks').clusterInfo.aksNodeCount]", + "aksAgentPoolNodeMaxCount": "[steps('section_aks').clusterInfo.aksNodeMaxCount]", "aksClusterName": "[last(split(steps('section_aks').clusterInfo.aksClusterSelector.id, '/'))]", "aksClusterRGName": "[last(take(split(steps('section_aks').clusterInfo.aksClusterSelector.id, '/'), 5))]", "appGatewayCertificateOption": "[steps('section_appGateway').appgwIngress.certificateOption]", - "appGatewaySSLBackendRootCertData": "[steps('section_appGateway').appgwIngress.keyVaultBackendSSLCertData]", - "appGatewaySSLCertData": "[steps('section_appGateway').appgwIngress.keyVaultSSLCertData]", + "appGatewaySSLBackendRootCertData": "[steps('section_appGateway').appgwIngress.uploadedSSLCertData]", + "appGatewaySSLCertData": "[steps('section_appGateway').appgwIngress.appGatewaySSLCertData]", "appGatewaySSLCertPassword": "[steps('section_appGateway').appgwIngress.appGatewaySSLCertPassword]", "appgwForAdminServer": "[steps('section_appGateway').appgwIngress.appgwForAdminServer]", "appgwForRemoteConsole": "[steps('section_appGateway').appgwIngress.appgwForAdminRemote]", + "appgwUsePrivateIP": "[steps('section_appGateway').appgwIngress.appgwUsePrivateIP]", "appPackageUrls": "[steps('section_aks').jeeAppInfo.appPackageUrl]", "appReplicas": "[int(steps('section_aks').jeeAppInfo.appReplicas)]", - "createACR": "[bool(steps('section_aks').acrInfo.createACR)]", + "averageCpuUtilization": "[steps('section_autoScaling').autoScalingInfo.averageCpuUtilization]", + "averageMemoryUtilization": "[steps('section_autoScaling').autoScalingInfo.averageMemoryUtilization]", + "createACR": "[bool(steps('section_aks').imageInfo.oracleCreateACR)]", "createAKSCluster": "[bool(steps('section_aks').clusterInfo.createAKSCluster)]", "createDNSZone": "[not(bool(steps('section_dnsConfiguration').bringDNSZone))]", + "dbDriverLibrariesUrls": "[steps('section_database').databaseConnectionInfo.dbDriverLibraries]", + "dbDriverName": "[steps('section_database').databaseConnectionInfo.dbDriverName]", + "dbGlobalTranPro": "[steps('section_database').databaseConnectionInfo.dbGlobalTranPro]", + "dbIdentity": "[steps('section_database').databaseConnectionInfo.dbIdentity]", "dbPassword": "[steps('section_database').databaseConnectionInfo.dbPassword]", + "dbTestTableName": "[steps('section_database').databaseConnectionInfo.dbTestTableName]", "dbUser": "[steps('section_database').databaseConnectionInfo.dbUser]", "databaseType": "[steps('section_database').databaseConnectionInfo.databaseType]", "dnszoneAdminConsoleLabel": "[steps('section_dnsConfiguration').dnszoneAdminConsoleLabel]", @@ -1675,40 +2135,27 @@ "dnszoneClusterT3ChannelLabel": "[steps('section_dnsConfiguration').dnszoneClusterT3ChannelLabel]", "dnszoneName": "[steps('section_dnsConfiguration').dnszoneName]", "dnszoneRGName": "[steps('section_dnsConfiguration').dnsZoneResourceGroup]", - "dsConnectionURL": "[steps('section_database').databaseConnectionInfo.dsConnectionURL]", - "enableAppGWIngress": "[steps('section_appGateway').appgwIngress.enableAppGateway]", - "enableAzureMonitoring": "[bool(steps('section_aks').clusterInfo.enableAzureMonitoring)]", - "enableAzureFileShare": "[bool(steps('section_aks').clusterInfo.enableAzureFileShare)]", - "enableCookieBasedAffinity": "[bool(steps('section_appGateway').appgwIngress.enableCookieBasedAffinity)]", + "dsConnectionURL": "[coalesce(steps('section_database').databaseConnectionInfo.dsConnectionURL, steps('section_database').databaseConnectionInfo.dsConnectionURL2, 'null')]", + "enableAppGWIngress": "[equals(steps('section_appGateway').loadBalancingOptions, 'agic')]", + "enableAutoscaling": "[bool(steps('section_autoScaling').enableAutoscaling)]", + "enableAzureMonitoring": "[bool(steps('section_aks').aksAdvancedInfo.enableAzureMonitoring)]", + "enableAzureFileShare": "[bool(steps('section_aks').aksAdvancedInfo.enableAzureFileShare)]", + "enableCookieBasedAffinity": "[not(bool(steps('section_appGateway').appgwIngress.enableCookieBasedAffinity))]", "enableCustomSSL": "[bool(steps('section_sslConfiguration').enableCustomSSL)]", "enableDB": "[bool(steps('section_database').enableDB)]", "enableDNSConfiguration": "[bool(steps('section_dnsConfiguration').enableDNSConfiguration)]", "enableAdminT3Tunneling": "[basics('basicsOptional').enableAdminT3Tunneling]", "enableClusterT3Tunneling": "[basics('basicsOptional').enableClusterT3Tunneling]", - "identity": "[basics('basicsRequired').identity]", + "enablePswlessConnection": "[or(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection), bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection0))]", "jdbcDataSourceName": "[steps('section_database').databaseConnectionInfo.jdbcDataSourceName]", - "lbSvcValues": "[steps('section_appGateway').lbSVCInfo.lbSVC]", + "isSSOSupportEntitled": "[bool(steps('section_aks').imageInfo.isSSOSupportEntitled)]", + "lbSvcValues": "[if(not(empty(first(if(empty(steps('section_appGateway').lbSVCInfo.lbSVC),parse('[{\"colName\":\"\"}]'), steps('section_appGateway').lbSVCInfo.lbSVC)).colName)),steps('section_appGateway').lbSVCInfo.lbSVC, parse('[]'))]", "location": "[location()]", - "keyVaultName": "[steps('section_appGateway').appgwIngress.keyVaultName]", - "keyVaultResourceGroup": "[steps('section_appGateway').appgwIngress.keyVaultResourceGroup]", - "keyVaultSSLBackendRootCertDataSecretName": "[steps('section_appGateway').appgwIngress.keyVaultBackendSSLCertDataSecretName]", - "keyVaultSSLCertDataSecretName": "[steps('section_appGateway').appgwIngress.keyVaultSSLCertDataSecretName]", - "keyVaultSSLCertPasswordSecretName": "[steps('section_appGateway').appgwIngress.keyVaultSSLCertPasswordSecretName]", + "hpaScaleType": "[steps('section_autoScaling').autoScalingInfo.kmsMetrics]", "managedServerPrefix": "[basics('basicsOptional').managedServerPrefix]", - "ocrSSOPSW": "[basics('basicsRequired').ocrSSOPassword]", - "ocrSSOUser": "[basics('basicsRequired').ocrSSOUserName]", - "servicePrincipal": "[steps('section_appGateway').appgwIngress.servicePrincipal]", - "sslConfigurationAccessOption": "[steps('section_sslConfiguration').sslConfigurationAccessOption]", - "sslKeyVaultCustomIdentityKeyStoreDataSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomIdentityKeyStoreDataSecretName]", - "sslKeyVaultCustomIdentityKeyStorePassPhraseSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomIdentityKeyStorePassPhraseSecretName]", - "sslKeyVaultCustomIdentityKeyStoreType": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomIdentityKeyStoreType]", - "sslKeyVaultCustomTrustKeyStoreDataSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomTrustKeyStoreDataSecretName]", - "sslKeyVaultCustomTrustKeyStorePassPhraseSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomTrustKeyStorePassPhraseSecretName]", - "sslKeyVaultCustomTrustKeyStoreType": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomTrustKeyStoreType]", - "sslKeyVaultName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultName]", - "sslKeyVaultPrivateKeyAliasSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultPrivateKeyAliasSecretName]", - "sslKeyVaultPrivateKeyPassPhraseSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultPrivateKeyPassPhraseSecretName]", - "sslKeyVaultResourceGroup": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultResourceGroup]", + "newOrExistingVnetForApplicationGateway": "[steps('section_appGateway').appgwIngress.vnetForApplicationGateway.newOrExisting]", + "ocrSSOPSW": "[steps('section_aks').imageInfo.ocrSSOPassword]", + "ocrSSOUser": "[steps('section_aks').imageInfo.ocrSSOUserName]", "sslUploadedCustomIdentityKeyStoreData": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomIdentityKeyStoreData]", "sslUploadedCustomIdentityKeyStorePassphrase": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomIdentityKeyStorePassphrase]", "sslUploadedCustomIdentityKeyStoreType": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomIdentityKeyStoreType]", @@ -1717,15 +2164,25 @@ "sslUploadedCustomTrustKeyStoreType": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomTrustKeyStoreType]", "sslUploadedPrivateKeyAlias": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedPrivateKeyAlias]", "sslUploadedPrivateKeyPassPhrase": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedPrivateKeyPassPhrase]", + "useHpa": "[if(equals(steps('section_autoScaling').autoScalingInfo.metricSource, 'kms'), true, false)]", "useInternalLB": "[bool(steps('section_appGateway').lbSVCInfo.enableInternalLB)]", + "useOracleImage": "[if(bool(steps('section_aks').aksAdvancedInfo.useAcrImage), false, true)]", + "userProvidedAcr": "[last(split(steps('section_aks').aksAdvancedInfo.userProvidedAcrSelector.id, '/'))]", + "userProvidedAcrRgName": "[last(take(split(steps('section_aks').aksAdvancedInfo.userProvidedAcrSelector.id, '/'),5))]", + "userProvidedImagePath": "[steps('section_aks').aksAdvancedInfo.userProvidedImagePath]", + "validateApplications": true, + "vnetForApplicationGateway": "[steps('section_appGateway').appgwIngress.vnetForApplicationGateway]", + "vnetRGNameForApplicationGateway": "[steps('section_appGateway').appgwIngress.vnetForApplicationGateway.resourceGroup]", + "vmSize": "[steps('section_aks').clusterInfo.nodeVMSizeSelector]", "wdtRuntimePassword": "[basics('basicsRequired').wdtRuntimePassword]", "wlsClusterSize": "[basics('basicsOptional').wlsClusterSize]", "wlsDomainName": "[basics('basicsOptional').wlsDomainName]", "wlsDomainUID": "[basics('basicsOptional').wlsDomainUID]", - "wlsImageTag": "[steps('section_aks').imageInfo.fromImage]", + "wlsImageTag": "[if(equals(steps('section_aks').imageInfo.oracleImageSelector, 'others'), steps('section_aks').imageInfo.fromOracleImage, steps('section_aks').imageInfo.oracleImageSelector)]", "wlsJavaOption": "[basics('basicsOptional').wlsJavaOption]", "wlsPassword": "[basics('basicsRequired').wlsPassword]", - "wlsUserName": "[basics('basicsRequired').wlsUserName]" + "wlsUserName": "[basics('basicsRequired').wlsUserName]", + "tagsByResource": "[steps('tags').tagsByResource]" } } } diff --git a/weblogic-azure-aks/src/main/arm/scripts/appgw-helm-config.yaml.template b/weblogic-azure-aks/src/main/arm/scripts/appgw-helm-config.yaml.template deleted file mode 100644 index 3f9dd7537..000000000 --- a/weblogic-azure-aks/src/main/arm/scripts/appgw-helm-config.yaml.template +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright (c) 2021, Oracle Corporation and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. -# -# Based on https://raw.githubusercontent.com/Azure/application-gateway-kubernetes-ingress/master/docs/examples/sample-helm-config.yaml - -# This file contains the essential configs for the ingress controller Helm chart - -# Verbosity level of the App Gateway Ingress Controller -verbosityLevel: 3 - -################################################################################ -# Specify which application gateway the ingress controller will manage -# -appgw: - subscriptionId: @SUB_ID@ - resourceGroup: @APPGW_RG_NAME@ - name: @APPGW_NAME@ - usePrivateIP: false - - # Setting appgw.shared to "true" will create an AzureIngressProhibitedTarget CRD. - # This prohibits AGIC from applying config for any host/path. - # Use "kubectl get AzureIngressProhibitedTargets" to view and change this. - shared: false - -################################################################################ -# Specify which Kubernetes namespace the ingress controller will watch -# Default value is "default" -# Leaving this variable out or setting it to blank or empty string would -# result in ingress controller observing all acessible namespaces. -# -kubernetes: - watchNamespace: @WATCH_NAMESPACE@ - -################################################################################ -# Specify the authentication with Azure Resource Manager -# -# Two authentication methods are available: -# - Option 1: AAD-Pod-Identity (https://github.com/Azure/aad-pod-identity) -# armAuth: -# type: aadPodIdentity -# identityResourceID: -# identityClientID: - -armAuth: - type: servicePrincipal - secretJSON: @SP_ENCODING_CREDENTIALS@ - -################################################################################ -# Specify if the cluster is RBAC enabled or not -rbac: - # Specifies whether RBAC resources should be created - create: true diff --git a/weblogic-azure-aks/src/main/arm/scripts/appgw-ingress-clusterAdmin-roleBinding.yaml b/weblogic-azure-aks/src/main/arm/scripts/appgw-ingress-clusterAdmin-roleBinding.yaml deleted file mode 100644 index 6bf39ce8e..000000000 --- a/weblogic-azure-aks/src/main/arm/scripts/appgw-ingress-clusterAdmin-roleBinding.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (c) 2021, Oracle Corporation and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: ingress-azure-admin -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: cluster-admin -subjects: -- kind: ServiceAccount - name: ingress-azure - namespace: default \ No newline at end of file diff --git a/weblogic-azure-aks/src/main/arm/scripts/buildWLSDockerImage.sh b/weblogic-azure-aks/src/main/arm/scripts/buildWLSDockerImage.sh index 0694ebe0d..0a4b7e58c 100644 --- a/weblogic-azure-aks/src/main/arm/scripts/buildWLSDockerImage.sh +++ b/weblogic-azure-aks/src/main/arm/scripts/buildWLSDockerImage.sh @@ -8,14 +8,14 @@ function echo_stderr() { echo "$@" >&2 } -# read and from stdin +# read and from stdin function read_sensitive_parameters_from_stdin() { - read azureACRPassword ocrSSOPSW + read azureACRShibboleth ocrSSOShibboleth } #Function to display usage message function usage() { - echo " ./buildWLSDockerImage.sh ./buildWLSDockerImage.sh " + echo " | ./buildWLSDockerImage.sh " if [ $1 -eq 1 ]; then exit 1 fi @@ -31,6 +31,11 @@ function validate_status() { } function validate_inputs() { + if [ -z "$useOracleImage" ]; then + echo_stderr "userProvidedImagePath is required. " + usage 1 + fi + if [ -z "$wlsImagePath" ]; then echo_stderr "wlsImagePath is required. " usage 1 @@ -46,8 +51,8 @@ function validate_inputs() { usage 1 fi - if [ -z "$azureACRPassword" ]; then - echo_stderr "azureACRPassword is required. " + if [ -z "$azureACRShibboleth" ]; then + echo_stderr "azureACRShibboleth is required. " usage 1 fi @@ -61,13 +66,13 @@ function validate_inputs() { usage 1 fi - if [ -z "$ocrSSOUser" ]; then + if [[ "${useOracleImage,,}" == "${constTrue}" ]] && [ -z "$ocrSSOUser" ]; then echo_stderr "ocrSSOUser is required. " usage 1 fi - if [ -z "$ocrSSOPSW" ]; then - echo_stderr "ocrSSOPSW is required. " + if [[ "${useOracleImage,,}" == "${constTrue}" ]] && [ -z "$ocrSSOShibboleth" ]; then + echo_stderr "ocrSSOShibboleth is required. " usage 1 fi @@ -90,6 +95,14 @@ function validate_inputs() { echo_stderr "enableClusterT3Tunneling is required. " usage 1 fi + + if [ -z "${dbDriversUrls}" ]; then + echo_stderr "dbDriversUrls is required. " + usage 1 + fi + + appPackageUrls=$(echo $appPackageUrls | base64 -d) + dbDriversUrls=$(echo $dbDriversUrls | base64 -d) } function initialize() { @@ -104,19 +117,90 @@ function initialize() { mkdir wlsdeploy mkdir wlsdeploy/config mkdir wlsdeploy/applications - mkdir wlsdeploy/domainLibraries + mkdir wlsdeploy/classpathLibraries + mkdir wlsdeploy/${externalJDBCLibrariesDirectoryName} } -# Install docker, zip, unzip and java -# Download WebLogic Tools -function install_utilities() { - # Install docker +function download_wdt_wit() { + local wlsToolingFamilyJsonFile=weblogic_tooling_family.json + # download the json file that has wls operator version from weblogic-azure repo. + curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -fsL "${gitUrl4WLSToolingFamilyJsonFile}" -o ${wlsToolingFamilyJsonFile} + if [ $? -eq 0 ]; then + wdtDownloadURL=$(cat ${wlsToolingFamilyJsonFile} | jq ".items[] | select(.key==\"WDT\") | .downloadURL" | tr -d "\"") + echo "WDT URL: ${wdtDownloadURL}" + witDownloadURL=$(cat ${wlsToolingFamilyJsonFile} | jq ".items[] | select(.key==\"WIT\") | .downloadURL" | tr -d "\"") + echo "WIT URL: ${witDownloadURL}" + else + echo "Use latest WDT and WIT." + wdtDownloadURL="https://github.com/oracle/weblogic-deploy-tooling/releases/latest/download/weblogic-deploy.zip" + witDownloadURL="https://github.com/oracle/weblogic-image-tool/releases/latest/download/imagetool.zip" + fi + + # Download weblogic tools + curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -fsL ${wdtDownloadURL} -o weblogic-deploy.zip + validate_status "Check status of weblogic-deploy.zip." + + curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -fsL ${witDownloadURL} -o imagetool.zip + validate_status "Check status of imagetool.zip." +} + +function download_azure_identity_extensions() { + local myPom=pom.xml + curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -fsL "${gitUrl4AzureIdentityExtensionsPomFile}" -o ${myPom} + validate_status "Check status of downloading Azure Identity Provider JDBC MySQL Pom file." + + echo "download dependencies" + mvn dependency:copy-dependencies -f ${myPom} + if [ $? -eq 0 ]; then + ls -l target/dependency/ + + mkdir wlsdeploy/classpathLibraries/azureLibraries + mkdir wlsdeploy/classpathLibraries/jackson + # fix JARs conflict issue in GA images, put jackson libraries to PRE_CLASSPATH to upgrade the existing libs. + mv target/dependency/jackson-annotations-*.jar wlsdeploy/classpathLibraries/jackson/ + mv target/dependency/jackson-core-*.jar wlsdeploy/classpathLibraries/jackson/ + mv target/dependency/jackson-databind-*.jar wlsdeploy/classpathLibraries/jackson/ + mv target/dependency/jackson-dataformat-xml-*.jar wlsdeploy/classpathLibraries/jackson/ + # Thoes jars will be appended to CLASSPATH + mv target/dependency/*.jar wlsdeploy/classpathLibraries/azureLibraries/ + else + echo "Failed to download dependencies for azure-identity-extensions" + exit 1 + fi +} + +function download_mysql_driver() { + local myPom=mysqlpom.xml + curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -fsL "${gitUrl4MySQLDriverPomFile}" -o ${myPom} + validate_status "Check status of downloading MySQL driver Pom file." + + echo "download dependencies" + mvn dependency:copy-dependencies -f ${myPom} + if [ $? -eq 0 ]; then + ls -l target/dependency/ + + mkdir wlsdeploy/${constPreclassDirectoryName} + mv target/dependency/*.jar wlsdeploy/${constPreclassDirectoryName}/ + else + echo "Failed to download dependencies for mysql driver." + exit 1 + fi +} + +function install_docker_multi_arch(){ + # Install docker https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository + # Add Docker's official GPG key: sudo apt-get -q update - sudo apt-get -y -q install apt-transport-https - curl -m ${curlMaxTime} -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg + sudo apt-get -y -q install ca-certificates curl + sudo install -m 0755 -d /etc/apt/keyrings + sudo curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc + sudo chmod a+r /etc/apt/keyrings/docker.asc + + # Add the repository to Apt sources: echo \ - "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ - $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list >/dev/null + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ + $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ + sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get -q update sudo apt-get -y -q install docker-ce docker-ce-cli containerd.io @@ -124,22 +208,57 @@ function install_utilities() { sudo docker --version validate_status "Check status of docker." sudo systemctl start docker +} +function install_openjdk11_x64(){ # Install Microsoft OpenJDK - wget https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb + # Valid values are only '18.04', '20.04', and '22.04' + ubuntu_release=`lsb_release -rs` + wget https://packages.microsoft.com/config/ubuntu/${ubuntu_release}/packages-microsoft-prod.deb -O packages-microsoft-prod.deb sudo dpkg -i packages-microsoft-prod.deb - sudo apt -q update - sudo apt -y -q install msopenjdk-11 + + sudo apt-get -y -q install apt-transport-https + sudo apt-get -q update + sudo apt-get -y -q install msopenjdk-11 echo "java version" java -version - validate_status "Check status of Zulu JDK 8." + validate_status "Check status of OpenJDK 11." + + + export JAVA_HOME=/usr/lib/jvm/msopenjdk-11-$(dpkg --print-architecture) + if [ ! -d "${JAVA_HOME}" ]; then + echo "Java home ${JAVA_HOME} does not exist." + exit 1 + fi +} + +function install_openjdk11_arm64(){ + local zipFileName="microsoft-jdk-11.tar.gz" + sudo curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -fsSL ${jdkArm64Url} -o ${zipFileName} + sudo mkdir -p /usr/lib/jvm + local dirName=$(sudo tar -xzvf ${zipFileName} | head -1 | cut -f1 -d"/") + sudo tar -xzvf ${zipFileName} + sudo mv ${dirName} msopenjdk-11-amd64 + sudo mv -f msopenjdk-11-amd64 /usr/lib/jvm/ export JAVA_HOME=/usr/lib/jvm/msopenjdk-11-amd64 if [ ! -d "${JAVA_HOME}" ]; then echo "Java home ${JAVA_HOME} does not exist" exit 1 fi +} + +# Install docker, zip, unzip and java +# Download WebLogic Tools +function install_utilities() { + install_docker_multi_arch + + if [[ "$(dpkg --print-architecture)" == "arm64" ]]; then + install_openjdk11_arm64 + else + install_openjdk11_x64 + fi sudo apt -y -q install zip zip --help @@ -150,26 +269,82 @@ function install_utilities() { unzip --help validate_status "Check status of unzip." - # Download weblogic tools - curl -m ${curlMaxTime} -fL ${wdtDownloadURL} -o weblogic-deploy.zip - validate_status "Check status of weblogic-deploy.zip." + sudo apt-get -y -q install jq + echo "jq version" + jq --help + validate_status "Check status of unzip." - curl -m ${curlMaxTime} -fL ${witDownloadURL} -o imagetool.zip - validate_status "Check status of imagetool.zip." + sudo apt -y -q install maven + mvn --help + validate_status "Check status of mvn." - curl -m ${curlMaxTime} -fL ${wlsPostgresqlDriverUrl} -o ${scriptDir}/model-images/wlsdeploy/domainLibraries/postgresql-42.2.8.jar - validate_status "Install postgresql driver." + download_wdt_wit - curl -m ${curlMaxTime} -fL ${wlsMSSQLDriverUrl} -o ${scriptDir}/model-images/wlsdeploy/domainLibraries/mssql-jdbc-7.4.1.jre8.jar - validate_status "Install mssql driver." + if [[ "${dbType}" == "postgresql" ]]; then + curl -m ${curlMaxTime} \ + --retry ${retryMaxAttempt} \ + -fL ${wlsPostgresqlDriverUrl} \ + -o ${scriptDir}/model-images/wlsdeploy/${externalJDBCLibrariesDirectoryName}/${constPostgreDriverName} + validate_status "Install postgresql driver." + fi + + if [[ "${dbType}" == "sqlserver" ]]; then + curl -m ${curlMaxTime} \ + --retry ${retryMaxAttempt} \ + -fL ${wlsMSSQLDriverUrl} \ + -o ${scriptDir}/model-images/wlsdeploy/${externalJDBCLibrariesDirectoryName}/${constMSSQLDriverName} + validate_status "Install mssql driver." + fi + + if [[ "${dbType}" == "mysql" ]]; then + download_mysql_driver + fi + + # for sqlserver. no need to install azure identity extensions + if [[ "${enablePswlessConnection,,}" == "true" ]] && [[ "${dbType}" == "mysql" || "${dbType}" == "postgresql" ]]; then + download_azure_identity_extensions + fi +} + +function install_db_drivers() { + if [ "${dbDriversUrls}" == "[]" ] || [ -z "${dbDriversUrls}" ]; then + return + fi + + local dbDriversUrls=$(echo "${dbDriversUrls:1:${#dbDriversUrls}-2}") + local dbDriversUrlsArray=$(echo $dbDriversUrls | tr "," "\n") + + for item in $dbDriversUrlsArray; do + echo ${item} + # e.g. https://wlsaksapp.blob.core.windows.net/japps/mariadb-java-client-2.7.4.jar?sp=r&se=2021-04-29T15:12:38Z&sv=2020-02-10&sr=b&sig=7grL4qP%2BcJ%2BLfDJgHXiDeQ2ZvlWosRLRQ1ciLk0Kl7M%3D + local urlWithoutQueryString="${item%\?*}" + echo $urlWithoutQueryString + local fileName="${urlWithoutQueryString##*/}" + echo $fileName + + curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -fL "$item" -o ${scriptDir}/model-images/wlsdeploy/${externalJDBCLibrariesDirectoryName}/${fileName} + if [ $? -ne 0 ];then + echo "Failed to download $item" + exit 1 + fi + done } # Login in OCR # Pull weblogic image function get_wls_image_from_ocr() { sudo docker logout - sudo docker login ${ocrLoginServer} -u ${ocrSSOUser} -p ${ocrSSOPSW} - echo "Start to pull image ${wlsImagePath}" + sudo docker login ${ocrLoginServer} -u ${ocrSSOUser} -p ${ocrSSOShibboleth} + echo "Start to pull oracle image ${wlsImagePath} ${ocrLoginServer} ${ocrSSOUser} ${ocrSSOShibboleth}" + sudo docker pull -q ${wlsImagePath} + validate_status "Finish pulling image from OCR." +} + +# Get user provided image +function get_user_provided_wls_image_from_acr() { + sudo docker logout + sudo docker login ${azureACRServer} -u ${azureACRUserName} -p ${azureACRShibboleth} + echo "Start to pull user provided image ${wlsImagePath} ${azureACRServer} ${azureACRUserName} ${azureACRShibboleth}" sudo docker pull -q ${wlsImagePath} validate_status "Finish pulling image from OCR." } @@ -208,6 +383,30 @@ function build_wls_image() { # Zip wls model and applications zip -r ${scriptDir}/model-images/archive.zip wlsdeploy + # inspect user/group of the base image + local imageInfo=$(./imagetool/bin/imagetool.sh inspect --image ${wlsImagePath}) + # { + # "os" : { + # "id" : "ol", + # "name" : "Oracle Linux Server", + # "version" : "7.9" + # }, + # "javaHome" : "/u01/jdk", + # "javaVersion" : "1.8.0_271", + # "oracleHome" : "/u01/oracle", + # "oracleHomeGroup" : "oracle", + # "oracleHomeUser" : "oracle", + # "oracleInstalledProducts" : "WLS,COH,TOPLINK", + # "packageManager" : "YUM", + # "wlsVersion" : "12.2.1.4.0" + # } + echo ${imageInfo} + local user=${imageInfo#*oracleHomeUser} + local user=$(echo ${user%%\,*} | tr -d "\"\:\ ") + local group=${imageInfo#*oracleHomeGroup} + local group=$(echo ${group%%\,*} | tr -d "\"\:\ ") + echo "use ${user}:${group} to update the image" + # Build image echo "Start building WLS image." ./imagetool/bin/imagetool.sh update \ @@ -218,8 +417,8 @@ function build_wls_image() { --wdtArchive ${scriptDir}/model-images/archive.zip \ --wdtModelOnly \ --wdtDomainType WLS \ - --chown oracle:root - # --additionalBuildCommands ${scriptDir}/nodemanager.dockerfile + --platform ${cpuPlatform} \ + --chown ${user}:${group} validate_status "Check status of building WLS domain image." @@ -227,7 +426,7 @@ function build_wls_image() { # Push image to ACR sudo docker logout - sudo docker login $azureACRServer -u ${azureACRUserName} -p ${azureACRPassword} + sudo docker login $azureACRServer -u ${azureACRUserName} -p ${azureACRShibboleth} echo "Start pushing image ${acrImagePath} to $azureACRServer." sudo docker push -q ${acrImagePath} validate_status "Check status of pushing WLS domain image." @@ -250,13 +449,13 @@ export wlsClusterSize=$7 export enableSSL=$8 export enableAdminT3Tunneling=$9 export enableClusterT3Tunneling=${10} +export useOracleImage=${11} +export dbDriversUrls=${12} +export enablePswlessConnection=${13} +export dbType=${14} +export cpuPlatform=${15} export acrImagePath="$azureACRServer/aks-wls-images:${imageTag}" -export ocrLoginServer="container-registry.oracle.com" -export wdtDownloadURL="https://github.com/oracle/weblogic-deploy-tooling/releases/download/release-1.9.17/weblogic-deploy.zip" -export witDownloadURL="https://github.com/oracle/weblogic-image-tool/releases/download/release-1.9.16/imagetool.zip" -export wlsPostgresqlDriverUrl="https://jdbc.postgresql.org/download/postgresql-42.2.8.jar" -export wlsMSSQLDriverUrl="https://repo.maven.apache.org/maven2/com/microsoft/sqlserver/mssql-jdbc/7.4.1.jre8/mssql-jdbc-7.4.1.jre8.jar" read_sensitive_parameters_from_stdin @@ -266,7 +465,13 @@ initialize install_utilities -get_wls_image_from_ocr +install_db_drivers + +if [[ "${useOracleImage,,}" == "${constTrue}" ]]; then + get_wls_image_from_ocr +else + get_user_provided_wls_image_from_acr +fi prepare_wls_models diff --git a/weblogic-azure-aks/src/main/arm/scripts/checkApplicationStatus.py b/weblogic-azure-aks/src/main/arm/scripts/checkApplicationStatus.py new file mode 100644 index 000000000..0936b1ffd --- /dev/null +++ b/weblogic-azure-aks/src/main/arm/scripts/checkApplicationStatus.py @@ -0,0 +1,58 @@ +# Copyright (c) 2021, Oracle Corporation and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +import sys + +def usage(): + print(sys.argv[0] + '-user -password -t3ChannelAddress
    -t3ChannelPort ') + +if len(sys.argv) < 4: + usage() + sys.exit(0) + +#domainUser is hard-coded to weblogic. You can change to other name of your choice. Command line paramter -user. +domainUser = 'weblogic' +#domainPassword will be passed by Command line parameter -password. +domainPassword = None +t3ChannelPort = None +t3ChannelAddress = None + +i = 1 +while i < len(sys.argv): + if sys.argv[i] == '-user': + domainUser = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-password': + domainPassword = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-t3ChannelAddress': + t3ChannelAddress = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-t3ChannelPort': + t3ChannelPort = sys.argv[i + 1] + i += 2 + else: + print('Unexpected argument switch at position ' + str(i) + ': ' + str(sys.argv[i])) + usage() + sys.exit(1) + +t3ConnectionUri='t3://'+t3ChannelAddress+':'+t3ChannelPort +connect(domainUser, domainPassword, t3ConnectionUri) +myapps=cmo.getAppDeployments() +inactiveApp=0 +for app in myapps: + bean=getMBean('/AppDeployments/'+app.getName()+'/Targets/') + targetsbean=bean.getTargets() + for target in targetsbean: + domainRuntime() + cd('AppRuntimeStateRuntime/AppRuntimeStateRuntime') + appstatus=cmo.getCurrentState(app.getName(),target.getName()) + if appstatus != 'STATE_ACTIVE': + inactiveApp=inactiveApp+1 + serverConfig() + +# TIGHT COUPLING: this exact print text is expected to indicate a successful return. +if inactiveApp == 0: + print("Summary: all applications are active!") +else: + print("Summary: number of inactive application: " + str(inactiveApp) + '.') diff --git a/weblogic-azure-aks/src/main/arm/scripts/common.sh b/weblogic-azure-aks/src/main/arm/scripts/common.sh index dcf214f3d..43b74eae4 100644 --- a/weblogic-azure-aks/src/main/arm/scripts/common.sh +++ b/weblogic-azure-aks/src/main/arm/scripts/common.sh @@ -1,20 +1,69 @@ +# Copyright (c) 2021, 2024, Oracle Corporation and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +# This script runs on Azure Container Instance with Alpine Linux that Azure Deployment script creates. + export checkPodStatusInterval=20 # interval of checking pod status. -export checkPodStatusMaxAttemps=30 # max attempt to check pod status. +export checkPodStatusMaxAttemps=200 # max attempt to check pod status. export checkPVStateInterval=5 # interval of checking pvc status. export checkPVStateMaxAttempt=10 # max attempt to check pvc status. -export checkSVCStateMaxAttempt=10 +export checkSVCStateMaxAttempt=50 export checkSVCInterval=30 #seconds +export checkAGICStatusMaxAttempt=10 +export checkAGICStatusInterval=30 +export checkIngressStateMaxAttempt=50 +export checkAcrInterval=30 +export checkAcrMaxAttempt=10 +export checkAgicInterval=30 +export checkAgicMaxAttempt=50 +export checkKedaInteval=30 +export checkKedaMaxAttempt=20 export constAdminT3AddressEnvName="T3_TUNNELING_ADMIN_ADDRESS" export constAdminServerName='admin-server' export constClusterName='cluster-1' export constClusterT3AddressEnvName="T3_TUNNELING_CLUSTER_ADDRESS" +export constARM64Platform="arm64" +export constX86Platform="amd64" +export constMultiArchPlatform="Multi-architecture" +export constDBTypeMySQL="mysql" +export constDBTypeSqlServer="sqlserver" +export constDefaultJavaOptions="-Dlog4j2.formatMsgNoLookups=true -Dweblogic.StdoutDebugEnabled=false" # the java options will be applied to the cluster +export constDefaultJVMArgs="-Djava.security.egd=file:/dev/./urandom -Xms256m -Xmx512m -XX:MinRAMPercentage=25.0 -XX:MaxRAMPercentage=50.0 " # the JVM options will be applied to the cluster +export constDefaultAKSVersion="default" +export externalJDBCLibrariesDirectoryName="externalJDBCLibraries" export constFalse="false" export constTrue="true" +export constIntrospectorJobActiveDeadlineSeconds=300 # for Guaranteed Qos +export constPostgreDriverName="postgresql-42.7.5.jar" +export constMSSQLDriverName="mssql-jdbc-11.2.3.jre8.jar" +export constAzureCoreVersion="1.34.0" +export constDbPodIdentitySelector="db-pod-identity" # do not change the value +export constPreclassDirectoryName="preclassLibraries" +export constLivenessProbePeriodSeconds=30 +export constLivenessProbeTimeoutSeconds=5 +export constLivenessProbeFailureThreshold=20 +export constReadinessProbeProbePeriodSeconds=10 +export constReadinessProbeTimeoutSeconds=5 +export constReadinessProbeFailureThreshold=3 export curlMaxTime=120 # seconds export ocrLoginServer="container-registry.oracle.com" +export ocrGaImagePath="middleware/weblogic" +export ocrCpuImagePath="middleware/weblogic_cpu" +export gitUrl4CpuImages="https://raw.githubusercontent.com/oracle/weblogic-azure/556ebc6bfd92679ceeb843f0a1bdea98a06ca608/weblogic-azure-aks/src/main/resources/weblogic_cpu_images.json" +export gitUrl4AksWellTestedVersionJsonFile="https://raw.githubusercontent.com/oracle/weblogic-azure/556ebc6bfd92679ceeb843f0a1bdea98a06ca608/weblogic-azure-aks/src/main/resources/aks_well_tested_version.json" +export gitUrl4AksToolingWellTestedVersionJsonFile="https://raw.githubusercontent.com/oracle/weblogic-azure/556ebc6bfd92679ceeb843f0a1bdea98a06ca608/weblogic-azure-aks/src/main/resources/aks_tooling_well_tested_versions.json" +export gitUrl4WLSToolingFamilyJsonFile="https://raw.githubusercontent.com/oracle/weblogic-azure/556ebc6bfd92679ceeb843f0a1bdea98a06ca608/weblogic-azure-aks/src/main/resources/weblogic_tooling_family.json" +export gitUrl4AzureIdentityExtensionsPomFile="https://raw.githubusercontent.com/oracle/weblogic-azure/556ebc6bfd92679ceeb843f0a1bdea98a06ca608/weblogic-azure-aks/src/main/resources/azure-identity-extensions.xml" +export gitUrl4MySQLDriverPomFile="https://raw.githubusercontent.com/oracle/weblogic-azure/556ebc6bfd92679ceeb843f0a1bdea98a06ca608/weblogic-azure-aks/src/main/resources/mysql-connector-java.xml" + export optUninstallMaxTry=5 # Max attempts to wait for the operator uninstalled export optUninstallInterval=10 +export retryMaxAttempt=5 # retry attempt for curl command +export retryInterval=10 + export wlsContainerName="weblogic-server" +export wlsPostgresqlDriverUrl="https://jdbc.postgresql.org/download/postgresql-42.7.5.jar" +export wlsMSSQLDriverUrl="https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/11.2.3.jre8/mssql-jdbc-11.2.3.jre8.jar" +export jdkArm64Url="https://aka.ms/download-jdk/microsoft-jdk-11.0.23-linux-aarch64.tar.gz" diff --git a/weblogic-azure-aks/src/main/arm/scripts/createAppGatewayIngress.sh b/weblogic-azure-aks/src/main/arm/scripts/createAppGatewayIngress.sh index a4d41688d..49916b55d 100644 --- a/weblogic-azure-aks/src/main/arm/scripts/createAppGatewayIngress.sh +++ b/weblogic-azure-aks/src/main/arm/scripts/createAppGatewayIngress.sh @@ -1,4 +1,4 @@ -# Copyright (c) 2021, Oracle Corporation and/or its affiliates. +# Copyright (c) 2021, 2024, Oracle Corporation and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. # Description: to create Azure Application Gateway ingress for the following targets. @@ -8,34 +8,26 @@ echo "Script ${0} starts" -# read from stdin -function read_sensitive_parameters_from_stdin() { - read spBase64String appgwFrontendSSLCertPsw -} - function generate_appgw_cluster_config_file_expose_https() { - clusterIngressHttpsName=${wlsDomainUID}-cluster-appgw-ingress-https-svc - clusterAppgwIngressHttpsYamlPath=${scriptDir}/appgw-cluster-ingress-https-svc.yaml - cat <${clusterAppgwIngressHttpsYamlPath} + clusterIngressHttpsName=${WLS_DOMAIN_UID}-cluster-appgw-ingress-https-svc + clusterAppgwIngressHttpsYamlPath=${scriptDir}/appgw-cluster-ingress-https-svc.yaml + cat <${clusterAppgwIngressHttpsYamlPath} apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ${clusterIngressHttpsName} namespace: ${wlsDomainNS} + labels: + weblogic.domainUID: "${WLS_DOMAIN_UID}" + azure.weblogic.target: "${constClusterName}" + azure.weblogc.createdByWlsOffer: "true" annotations: - kubernetes.io/ingress.class: azure/application-gateway -EOF - - if [[ "${enableCookieBasedAffinity,,}" == "true" ]]; then - cat <>${clusterAppgwIngressHttpsYamlPath} - appgw.ingress.kubernetes.io/cookie-based-affinity: "true" -EOF - fi - - cat <>${clusterAppgwIngressHttpsYamlPath} + appgw.ingress.kubernetes.io/appgw-ssl-certificate: "${APPGW_SSL_CERT_NAME}" + appgw.ingress.kubernetes.io/use-private-ip: "${APPGW_USE_PRIVATE_IP}" + appgw.ingress.kubernetes.io/cookie-based-affinity: "${ENABLE_COOKIE_BASED_AFFINITY}" + appgw.ingress.kubernetes.io/backend-path-prefix: "/" spec: - tls: - - secretName: ${appgwFrontendSecretName} + ingressClassName: azure-application-gateway rules: - http: paths: @@ -50,26 +42,24 @@ EOF } function generate_appgw_cluster_config_file_nossl() { - clusterIngressName=${wlsDomainUID}-cluster-appgw-ingress-svc - clusterAppgwIngressYamlPath=${scriptDir}/appgw-cluster-ingress-svc.yaml - cat <${clusterAppgwIngressYamlPath} + clusterIngressName=${WLS_DOMAIN_UID}-cluster-appgw-ingress-svc + clusterAppgwIngressYamlPath=${scriptDir}/appgw-cluster-ingress-svc.yaml + cat <${clusterAppgwIngressYamlPath} apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ${clusterIngressName} namespace: ${wlsDomainNS} + labels: + weblogic.domainUID: "${WLS_DOMAIN_UID}" + azure.weblogic.target: "${constClusterName}" + azure.weblogc.createdByWlsOffer: "true" annotations: - kubernetes.io/ingress.class: azure/application-gateway -EOF - - if [[ "${enableCookieBasedAffinity,,}" == "true" ]]; then - cat <>${clusterAppgwIngressYamlPath} - appgw.ingress.kubernetes.io/cookie-based-affinity: "true" -EOF - fi - - cat <>${clusterAppgwIngressYamlPath} + appgw.ingress.kubernetes.io/use-private-ip: "${APPGW_USE_PRIVATE_IP}" + appgw.ingress.kubernetes.io/cookie-based-affinity: "${ENABLE_COOKIE_BASED_AFFINITY}" + appgw.ingress.kubernetes.io/backend-path-prefix: "/" spec: + ingressClassName: azure-application-gateway rules: - http: paths: @@ -84,41 +74,41 @@ EOF } function generate_appgw_cluster_config_file_ssl() { - clusterIngressName=${wlsDomainUID}-cluster-appgw-ingress-svc - clusterAppgwIngressYamlPath=${scriptDir}/appgw-cluster-ingress-svc.yaml - cat <${clusterAppgwIngressYamlPath} + clusterIngressName=${WLS_DOMAIN_UID}-cluster-appgw-ingress-svc + clusterAppgwIngressYamlPath=${scriptDir}/appgw-cluster-ingress-svc.yaml + cat <${clusterAppgwIngressYamlPath} apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ${clusterIngressName} namespace: ${wlsDomainNS} + labels: + weblogic.domainUID: "${WLS_DOMAIN_UID}" + azure.weblogic.target: "${constClusterName}" + azure.weblogc.createdByWlsOffer: "true" annotations: - kubernetes.io/ingress.class: azure/application-gateway appgw.ingress.kubernetes.io/ssl-redirect: "true" appgw.ingress.kubernetes.io/backend-protocol: "https" + appgw.ingress.kubernetes.io/appgw-ssl-certificate: "${APPGW_SSL_CERT_NAME}" + appgw.ingress.kubernetes.io/use-private-ip: "${APPGW_USE_PRIVATE_IP}" + appgw.ingress.kubernetes.io/cookie-based-affinity: "${ENABLE_COOKIE_BASED_AFFINITY}" + appgw.ingress.kubernetes.io/backend-path-prefix: "/" EOF - if [[ "${enableCustomDNSAlias,,}" == "true" ]]; then - cat <>${clusterAppgwIngressYamlPath} - appgw.ingress.kubernetes.io/backend-hostname: "${dnsClusterLabel}.${dnsZoneName}" -EOF - else - cat <>${clusterAppgwIngressYamlPath} - appgw.ingress.kubernetes.io/backend-hostname: "${appgwAlias}" + if [[ "${ENABLE_DNS_CONFIGURATION,,}" == "true" ]]; then + cat <>${clusterAppgwIngressYamlPath} + appgw.ingress.kubernetes.io/backend-hostname: "${DNS_CLUSTER_LABEL}.${DNS_ZONE_NAME}" EOF - fi - - if [[ "${enableCookieBasedAffinity,,}" == "true" ]]; then - cat <>${clusterAppgwIngressYamlPath} - appgw.ingress.kubernetes.io/cookie-based-affinity: "true" + else + cat <>${clusterAppgwIngressYamlPath} + appgw.ingress.kubernetes.io/backend-hostname: "${APPGW_ALIAS}" EOF - fi + fi - cat <>${clusterAppgwIngressYamlPath} - appgw.ingress.kubernetes.io/appgw-trusted-root-certificate: "${appgwBackendSecretName}" + cat <>${clusterAppgwIngressYamlPath} + appgw.ingress.kubernetes.io/appgw-trusted-root-certificate: "${APPGW_TRUSTED_ROOT_CERT_NAME}" spec: - tls: - - secretName: ${appgwFrontendSecretName} + ingressClassName: azure-application-gateway rules: - http: paths: @@ -133,26 +123,23 @@ EOF } function generate_appgw_admin_config_file_nossl() { - adminIngressName=${wlsDomainUID}-admin-appgw-ingress-svc - adminAppgwIngressYamlPath=${scriptDir}/appgw-admin-ingress-svc.yaml - cat <${adminAppgwIngressYamlPath} + adminIngressName=${WLS_DOMAIN_UID}-admin-appgw-ingress-svc + adminAppgwIngressYamlPath=${scriptDir}/appgw-admin-ingress-svc.yaml + cat <${adminAppgwIngressYamlPath} apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ${adminIngressName} namespace: ${wlsDomainNS} + labels: + weblogic.domainUID: "${WLS_DOMAIN_UID}" + azure.weblogic.target: "${constAdminServerName}" + azure.weblogc.createdByWlsOffer: "true" annotations: - kubernetes.io/ingress.class: azure/application-gateway -EOF - - if [[ "${enableCookieBasedAffinity,,}" == "true" ]]; then - cat <>${adminAppgwIngressYamlPath} - appgw.ingress.kubernetes.io/cookie-based-affinity: "true" -EOF - fi - - cat <>${adminAppgwIngressYamlPath} + appgw.ingress.kubernetes.io/use-private-ip: "${APPGW_USE_PRIVATE_IP}" + appgw.ingress.kubernetes.io/cookie-based-affinity: "${ENABLE_COOKIE_BASED_AFFINITY}" spec: + ingressClassName: azure-application-gateway rules: - http: paths: @@ -167,25 +154,22 @@ EOF } function generate_appgw_admin_remote_config_file_nossl() { - cat <${adminRemoteAppgwIngressYamlPath} + cat <${adminRemoteAppgwIngressYamlPath} apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ${adminRemoteIngressName} namespace: ${wlsDomainNS} + labels: + weblogic.domainUID: "${WLS_DOMAIN_UID}" + azure.weblogic.target: "${constAdminServerName}-remote-console" + azure.weblogc.createdByWlsOffer: "true" annotations: - kubernetes.io/ingress.class: azure/application-gateway appgw.ingress.kubernetes.io/backend-path-prefix: "/" -EOF - - if [[ "${enableCookieBasedAffinity,,}" == "true" ]]; then - cat <>${adminRemoteAppgwIngressYamlPath} - appgw.ingress.kubernetes.io/cookie-based-affinity: "true" -EOF - fi - - cat <>${adminRemoteAppgwIngressYamlPath} + appgw.ingress.kubernetes.io/use-private-ip: "${APPGW_USE_PRIVATE_IP}" + appgw.ingress.kubernetes.io/cookie-based-affinity: "${ENABLE_COOKIE_BASED_AFFINITY}" spec: + ingressClassName: azure-application-gateway rules: - http: paths: @@ -200,42 +184,41 @@ EOF } function generate_appgw_admin_config_file_ssl() { - adminIngressName=${wlsDomainUID}-admin-appgw-ingress-svc - adminAppgwIngressYamlPath=${scriptDir}/appgw-admin-ingress-svc.yaml - cat <${adminAppgwIngressYamlPath} + adminIngressName=${WLS_DOMAIN_UID}-admin-appgw-ingress-svc + adminAppgwIngressYamlPath=${scriptDir}/appgw-admin-ingress-svc.yaml + cat <${adminAppgwIngressYamlPath} apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ${adminIngressName} namespace: ${wlsDomainNS} + labels: + weblogic.domainUID: "${WLS_DOMAIN_UID}" + azure.weblogic.target: "${constAdminServerName}" + azure.weblogc.createdByWlsOffer: "true" annotations: - kubernetes.io/ingress.class: azure/application-gateway appgw.ingress.kubernetes.io/ssl-redirect: "true" appgw.ingress.kubernetes.io/backend-protocol: "https" + appgw.ingress.kubernetes.io/appgw-ssl-certificate: "${APPGW_SSL_CERT_NAME}" + appgw.ingress.kubernetes.io/use-private-ip: "${APPGW_USE_PRIVATE_IP}" + appgw.ingress.kubernetes.io/cookie-based-affinity: "${ENABLE_COOKIE_BASED_AFFINITY}" EOF - if [[ "${enableCustomDNSAlias,,}" == "true" ]]; then - cat <>${adminAppgwIngressYamlPath} - appgw.ingress.kubernetes.io/backend-hostname: "${dnsAdminLabel}.${dnsZoneName}" -EOF - else - cat <>${adminAppgwIngressYamlPath} - appgw.ingress.kubernetes.io/backend-hostname: "${appgwAlias}" + if [[ "${ENABLE_DNS_CONFIGURATION,,}" == "true" ]]; then + cat <>${adminAppgwIngressYamlPath} + appgw.ingress.kubernetes.io/backend-hostname: "${DNS_ADMIN_LABEL}.${DNS_ZONE_NAME}" EOF - fi - - if [[ "${enableCookieBasedAffinity,,}" == "true" ]]; then - cat <>${adminAppgwIngressYamlPath} - appgw.ingress.kubernetes.io/cookie-based-affinity: "true" + else + cat <>${adminAppgwIngressYamlPath} + appgw.ingress.kubernetes.io/backend-hostname: "${APPGW_ALIAS}" EOF - fi + fi - cat <>${adminAppgwIngressYamlPath} - appgw.ingress.kubernetes.io/appgw-trusted-root-certificate: "${appgwBackendSecretName}" + cat <>${adminAppgwIngressYamlPath} + appgw.ingress.kubernetes.io/appgw-trusted-root-certificate: "${APPGW_TRUSTED_ROOT_CERT_NAME}" spec: - tls: - - secretName: ${appgwFrontendSecretName} + ingressClassName: azure-application-gateway rules: - http: paths: @@ -250,42 +233,40 @@ EOF } function generate_appgw_admin_remote_config_file_ssl() { - cat <${adminRemoteAppgwIngressYamlPath} + cat <${adminRemoteAppgwIngressYamlPath} apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ${adminRemoteIngressName} namespace: ${wlsDomainNS} + labels: + weblogic.domainUID: "${WLS_DOMAIN_UID}" + azure.weblogic.target: "${constAdminServerName}-remote-console" + azure.weblogc.createdByWlsOffer: "true" annotations: - kubernetes.io/ingress.class: azure/application-gateway appgw.ingress.kubernetes.io/backend-path-prefix: "/" appgw.ingress.kubernetes.io/ssl-redirect: "true" appgw.ingress.kubernetes.io/backend-protocol: "https" - + appgw.ingress.kubernetes.io/appgw-ssl-certificate: "${APPGW_SSL_CERT_NAME}" + appgw.ingress.kubernetes.io/use-private-ip: "${APPGW_USE_PRIVATE_IP}" + appgw.ingress.kubernetes.io/cookie-based-affinity: "${ENABLE_COOKIE_BASED_AFFINITY}" EOF - if [[ "${enableCustomDNSAlias,,}" == "true" ]]; then - cat <>${adminRemoteAppgwIngressYamlPath} - appgw.ingress.kubernetes.io/backend-hostname: "${dnsAdminLabel}.${dnsZoneName}" + if [[ "${ENABLE_DNS_CONFIGURATION,,}" == "true" ]]; then + cat <>${adminRemoteAppgwIngressYamlPath} + appgw.ingress.kubernetes.io/backend-hostname: "${DNS_ADMIN_LABEL}.${DNS_ZONE_NAME}" EOF - else - cat <>${adminRemoteAppgwIngressYamlPath} - appgw.ingress.kubernetes.io/backend-hostname: "${appgwAlias}" + else + cat <>${adminRemoteAppgwIngressYamlPath} + appgw.ingress.kubernetes.io/backend-hostname: "${APPGW_ALIAS}" EOF - fi + fi - if [[ "${enableCookieBasedAffinity,,}" == "true" ]]; then - cat <>${adminRemoteAppgwIngressYamlPath} - appgw.ingress.kubernetes.io/cookie-based-affinity: "true" -EOF - fi - - cat <>${adminRemoteAppgwIngressYamlPath} - appgw.ingress.kubernetes.io/appgw-trusted-root-certificate: "${appgwBackendSecretName}" + cat <>${adminRemoteAppgwIngressYamlPath} + appgw.ingress.kubernetes.io/appgw-trusted-root-certificate: "${APPGW_TRUSTED_ROOT_CERT_NAME}" spec: - tls: - - secretName: ${appgwFrontendSecretName} + ingressClassName: azure-application-gateway rules: - http: paths: @@ -300,293 +281,265 @@ EOF } function query_admin_target_port() { - if [[ "${enableCustomSSL,,}" == "true" ]]; then - adminTargetPort=$(utility_query_service_port ${svcAdminServer} ${wlsDomainNS} 'default-secure') - else - adminTargetPort=$(utility_query_service_port ${svcAdminServer} ${wlsDomainNS} 'default') - fi + if [[ "${ENABLE_CUSTOM_SSL,,}" == "true" ]]; then + adminTargetPort=$(utility_query_service_port ${svcAdminServer} ${wlsDomainNS} 'internal-t3s') + else + adminTargetPort=$(utility_query_service_port ${svcAdminServer} ${wlsDomainNS} 'internal-t3') + fi - echo "Admin port of ${adminServerName}: ${adminTargetPort}" + echo "Admin port of ${adminServerName}: ${adminTargetPort}" } # Create network peers for aks and appgw function network_peers_aks_appgw() { - # To successfully peer two virtual networks command 'az network vnet peering create' must be called twice with the values - # for --vnet-name and --remote-vnet reversed. - aksMCRGName=$(az aks show -n $aksClusterName -g $aksClusterRGName -o tsv --query "nodeResourceGroup") - ret=$(az group exists -n ${aksMCRGName}) - if [ "${ret,,}" == "false" ]; then - echo_stderr "AKS namaged resource group ${aksMCRGName} does not exist." - exit 1 - fi - - aksNetWorkId=$(az resource list -g ${aksMCRGName} --resource-type Microsoft.Network/virtualNetworks -o tsv --query '[*].id') - aksNetworkName=$(az resource list -g ${aksMCRGName} --resource-type Microsoft.Network/virtualNetworks -o tsv --query '[*].name') - az network vnet peering create \ - --name aks-appgw-peer \ - --remote-vnet ${aksNetWorkId} \ - --resource-group ${curRGName} \ - --vnet-name ${vnetName} \ - --allow-vnet-access - utility_validate_status "Create network peers for $aksNetWorkId and ${vnetName}." - - appgwNetworkId=$(az resource list -g ${curRGName} --name ${vnetName} -o tsv --query '[*].id') + # To successfully peer two virtual networks command 'az network vnet peering create' must be called twice with the values + # for --vnet-name and --remote-vnet reversed. + + local aksMCRGName=$(az aks show -n $AKS_CLUSTER_NAME -g $AKS_CLUSTER_RG_NAME -o tsv --query "nodeResourceGroup") + local ret=$(az group exists -n ${aksMCRGName}) + if [ "${ret,,}" == "false" ]; then + echo_stderr "AKS namaged resource group ${aksMCRGName} does not exist." + exit 1 + fi + + # query vnet from managed resource group + local aksNetWorkId=$(az resource list -g ${aksMCRGName} --resource-type Microsoft.Network/virtualNetworks -o tsv --query '[*].id') + + # no vnet in managed resource group, then query vnet from aks agent + if [ -z "${aksNetWorkId}" ]; then + # assume all the agent pools are in the same vnet + # e.g. /subscriptions/xxxx-xxxx-xxxx-xxxx/resourceGroups/foo-rg/providers/Microsoft.Network/virtualNetworks/foo-aks-vnet/subnets/default + local aksAgent1Subnet=$(az aks show -n $AKS_CLUSTER_NAME -g $AKS_CLUSTER_RG_NAME | jq '.agentPoolProfiles[0] | .vnetSubnetId' | tr -d "\"") + utility_validate_status "Get subnet id of aks agent 0." + aksNetWorkId=${aksAgent1Subnet%\/subnets\/*} + fi + + local aksNetworkName=${aksNetWorkId#*\/virtualNetworks\/} + local aksNetworkRgName=${aksNetWorkId#*\/resourceGroups\/} + local aksNetworkRgName=${aksNetworkRgName%\/providers\/*} + + local appGatewaySubnetId=$(az network application-gateway show -g ${CURRENT_RG_NAME} --name ${APPGW_NAME} -o tsv --query "gatewayIPConfigurations[0].subnet.id") + local appGatewayVnetResourceGroup=$(az network application-gateway show -g ${CURRENT_RG_NAME} --name ${APPGW_NAME} -o tsv --query "gatewayIPConfigurations[0].subnet.resourceGroup") + local appgwNetworkId=${appGatewaySubnetId%\/subnets\/*} + local appgwVnetName=$(az resource show --ids ${appgwNetworkId} --query "name" -o tsv) + + local toPeer=true + # if the AKS and App Gateway have the same VNET, need not peer. + if [ "${aksNetWorkId}" == "${appgwNetworkId}" ]; then + echo_stdout "AKS and Application Gateway are in the same virtual network: ${appgwNetworkId}." + toPeer=false + fi + + # check if the Vnets have been peered. + local ret=$(az network vnet peering list \ + --resource-group ${appGatewayVnetResourceGroup} \ + --vnet-name ${appgwVnetName} -o json | + jq ".[] | select(.remoteVirtualNetwork.id==\"${aksNetWorkId}\")") + if [ -n "$ret" ]; then + echo_stdout "VNET of AKS ${aksNetWorkId} and Application Gateway ${appgwNetworkId} is peering." + toPeer=false + fi + + if [ "${toPeer}" == "true" ]; then az network vnet peering create \ - --name aks-appgw-peer \ - --remote-vnet ${appgwNetworkId} \ - --resource-group ${aksMCRGName} \ - --vnet-name ${aksNetworkName} \ - --allow-vnet-access - - utility_validate_status "Create network peers for $aksNetWorkId and ${vnetName}." + --name aks-appgw-peer \ + --remote-vnet ${aksNetWorkId} \ + --resource-group ${appGatewayVnetResourceGroup} \ + --vnet-name ${appgwVnetName} \ + --allow-vnet-access + utility_validate_status "Create network peers for $aksNetWorkId and ${appgwNetworkId}." - # For Kbectl network plugin: https://azure.github.io/application-gateway-kubernetes-ingress/how-tos/networking/#with-kubenet - # find route table used by aks cluster + az network vnet peering create \ + --name aks-appgw-peer \ + --remote-vnet ${appgwNetworkId} \ + --resource-group ${aksNetworkRgName} \ + --vnet-name ${aksNetworkName} \ + --allow-vnet-access + + utility_validate_status "Complete creating network peers for $aksNetWorkId and ${appgwNetworkId}." + fi + + # For kubenet network plugin: https://azure.github.io/application-gateway-kubernetes-ingress/how-tos/networking/#with-kubenet + # find route table used by aks cluster + local networkPlugin=$(az aks show -n $AKS_CLUSTER_NAME -g $AKS_CLUSTER_RG_NAME --query "networkProfile.networkPlugin" -o tsv) + if [[ "${networkPlugin}" == "kubenet" ]]; then + # the route table is in MC_ resource group routeTableId=$(az network route-table list -g $aksMCRGName --query "[].id | [0]" -o tsv) - # get the application gateway's subnet - appGatewaySubnetId=$(az network application-gateway show -n $appgwName -g $curRGName -o tsv --query "gatewayIpConfigurations[0].subnet.id") - # associate the route table to Application Gateway's subnet az network vnet subnet update \ --ids $appGatewaySubnetId \ --route-table $routeTableId utility_validate_status "Associate the route table ${routeTableId} to Application Gateway's subnet ${appGatewaySubnetId}" + fi } function query_cluster_target_port() { - if [[ "${enableCustomSSL,,}" == "true" ]]; then - clusterTargetPort=$(utility_query_service_port ${svcCluster} ${wlsDomainNS} 'default-secure') - else - clusterTargetPort=$(utility_query_service_port ${svcCluster} ${wlsDomainNS} 'default') - fi + if [[ "${ENABLE_CUSTOM_SSL,,}" == "true" ]]; then + clusterTargetPort=$(utility_query_service_port ${svcCluster} ${wlsDomainNS} 'default-secure') + else + clusterTargetPort=$(utility_query_service_port ${svcCluster} ${wlsDomainNS} 'default') + fi - echo "Cluster port of ${clusterName}: ${clusterTargetPort}" + echo "Cluster port of ${clusterName}: ${clusterTargetPort}" } -function install_azure_ingress() { - # create sa and bind cluster-admin role - # grant azure ingress permission to access WebLogic service - kubectl apply -f ${scriptDir}/appgw-ingress-clusterAdmin-roleBinding.yaml - - install_helm - helm repo add application-gateway-kubernetes-ingress ${appgwIngressHelmRepo} - helm repo update - - # generate Helm config for azure ingress - customAppgwHelmConfig=${scriptDir}/appgw-helm-config.yaml - cp ${scriptDir}/appgw-helm-config.yaml.template ${customAppgwHelmConfig} - subID=${subID#*\/subscriptions\/} - sed -i -e "s:@SUB_ID@:${subID}:g" ${customAppgwHelmConfig} - sed -i -e "s:@APPGW_RG_NAME@:${curRGName}:g" ${customAppgwHelmConfig} - sed -i -e "s:@APPGW_NAME@:${appgwName}:g" ${customAppgwHelmConfig} - sed -i -e "s:@WATCH_NAMESPACE@:${wlsDomainNS}:g" ${customAppgwHelmConfig} - sed -i -e "s:@SP_ENCODING_CREDENTIALS@:${spBase64String}:g" ${customAppgwHelmConfig} - - helm install ingress-azure \ - -f ${customAppgwHelmConfig} \ - application-gateway-kubernetes-ingress/ingress-azure \ - --version ${azureAppgwIngressVersion} - - utility_validate_status "Install app gateway ingress controller." - - attempts=0 - podState="running" - while [ "$podState" == "running" ] && [ $attempts -lt ${checkPodStatusMaxAttemps} ]; do - podState="completed" - attempts=$((attempts + 1)) - echo Waiting for Pod running...${attempts} - sleep ${checkPodStatusInterval} - - ret=$(kubectl get pod -o json | - jq '.items[] | .status.containerStatuses[] | select(.name=="ingress-azure") | .ready') - if [[ "${ret}" == "false" ]]; then - podState="running" - fi - done - - if [ "$podState" == "running" ] && [ $attempts -ge ${checkPodStatusMaxAttemps} ]; then - echo_stderr "Failed to install app gateway ingress controller." - exit 1 - fi +function generate_appgw_cluster_config_file() { + if [[ "${ENABLE_CUSTOM_SSL,,}" == "true" ]]; then + generate_appgw_cluster_config_file_ssl + else + generate_appgw_cluster_config_file_nossl + generate_appgw_cluster_config_file_expose_https + fi } -function output_create_gateway_ssl_k8s_secret() { - echo "export gateway frontend certificates" - echo "$appgwFrontendSSLCertData" | base64 -d >${scriptDir}/$appgwFrontCertFileName - - appgwFrontendSSLCertPassin=${appgwFrontendSSLCertPsw} - if [[ "$appgwCertificateOption" == "${appgwSelfsignedCert}" ]]; then - appgwFrontendSSLCertPassin="" # empty password - fi - - openssl pkcs12 \ - -in ${scriptDir}/$appgwFrontCertFileName \ - -nocerts \ - -out ${scriptDir}/$appgwFrontCertKeyFileName \ - -passin pass:${appgwFrontendSSLCertPassin} \ - -passout pass:${appgwFrontendSSLCertPsw} - - utility_validate_status "Export key from frontend certificate." - - openssl rsa -in ${scriptDir}/$appgwFrontCertKeyFileName \ - -out ${scriptDir}/$appgwFrontCertKeyDecrytedFileName \ - -passin pass:${appgwFrontendSSLCertPsw} - - utility_validate_status "Decryte private key." - - openssl pkcs12 \ - -in ${scriptDir}/$appgwFrontCertFileName \ - -clcerts \ - -nokeys \ - -out ${scriptDir}/$appgwFrontPublicCertFileName \ - -passin pass:${appgwFrontendSSLCertPassin} - - utility_validate_status "Export cert from frontend certificate." - - echo "create k8s tsl secret for app gateway frontend ssl termination" - kubectl -n ${wlsDomainNS} create secret tls ${appgwFrontendSecretName} \ - --key="${scriptDir}/$appgwFrontCertKeyDecrytedFileName" \ - --cert="${scriptDir}/$appgwFrontPublicCertFileName" - - utility_validate_status "create k8s tsl secret for app gateway frontend ssl termination." +function generate_appgw_admin_config_file() { + if [[ "${ENABLE_CUSTOM_SSL,,}" == "true" ]]; then + generate_appgw_admin_config_file_ssl + else + generate_appgw_admin_config_file_nossl + fi } -function validate_backend_ca_cert() { - az network application-gateway root-cert list \ - --gateway-name $appgwName \ - --resource-group $curRGName | - jq '.[] | .name' | grep "${appgwBackendSecretName}" - - utility_validate_status "check if backend cert exists." +function generate_appgw_admin_remote_config_file() { + if [[ "${ENABLE_CUSTOM_SSL,,}" == "true" ]]; then + generate_appgw_admin_remote_config_file_ssl + else + generate_appgw_admin_remote_config_file_nossl + fi } -function generate_appgw_cluster_config_file() { - if [[ "${enableCustomSSL,,}" == "true" ]]; then - generate_appgw_cluster_config_file_ssl - else - generate_appgw_cluster_config_file_nossl - generate_appgw_cluster_config_file_expose_https - fi -} +# Currently, ingress controller does not have a tag that identifies it's ready to create ingress. +# This function is to create an ingress and check it's status. If the ingress is not available, then re-create it again. +function waitfor_agic_ready_and_create_ingress() { + local svcName=$1 + local ymlFilePath=$2 + + local ready=false + local attempt=0 + while [[ "${ready}" == "false" && $attempt -lt ${checkAGICStatusMaxAttempt} ]]; do + echo "Waiting for AGIC ready... ${attempt}" + attempt=$((attempt + 1)) + kubectl apply -f ${ymlFilePath} + + # wait for the ingress ready, if the ingress is not available then delete it + local svcAttempts=0 + local svcState="running" + while [ "$svcState" == "running" ] && [ $svcAttempts -lt ${checkIngressStateMaxAttempt} ]; do + svcAttempts=$((svcAttempts + 1)) + echo Waiting for job completed...${svcAttempts} + sleep ${checkSVCInterval} + + ip=$(kubectl get ingress ${svcName} -n ${wlsDomainNS} -o json | + jq '.status.loadBalancer.ingress[0].ip') + echo "ip: ${ip}" + if [[ "${ip}" != "null" ]]; then + svcState="completed" + ready=true + fi + done -function generate_appgw_admin_config_file() { - if [[ "${enableCustomSSL,,}" == "true" ]]; then - generate_appgw_admin_config_file_ssl - else - generate_appgw_admin_config_file_nossl + if [[ "${ready}" == "false" ]]; then + kubectl delete -f ${ymlFilePath} + sleep ${checkAGICStatusInterval} fi -} + done + + if [ ${attempt} -ge ${checkAGICStatusMaxAttempt} ]; then + echo_stderr "azure igress is not ready to create ingress. " + exit 1 + fi -function generate_appgw_admin_remote_config_file() { - if [[ "${enableCustomSSL,,}" == "true" ]]; then - generate_appgw_admin_remote_config_file_ssl - else - generate_appgw_admin_remote_config_file_nossl - fi } function appgw_ingress_svc_for_cluster() { - # generate ingress svc config for cluster - generate_appgw_cluster_config_file - kubectl apply -f ${clusterAppgwIngressYamlPath} - utility_validate_status "Create appgw ingress svc." + # generate ingress svc config for cluster + generate_appgw_cluster_config_file + kubectl apply -f ${clusterAppgwIngressYamlPath} + utility_validate_status "Create appgw ingress svc." + waitfor_agic_ready_and_create_ingress \ + ${clusterIngressName} \ + ${clusterAppgwIngressYamlPath} + + # expose https for cluster if e2e ssl is not set up. + if [[ "${ENABLE_CUSTOM_SSL,,}" != "true" ]]; then + kubectl apply -f ${clusterAppgwIngressHttpsYamlPath} + utility_validate_status "Create appgw ingress https svc." utility_waitfor_ingress_completed \ - ${clusterIngressName} \ - ${wlsDomainNS} \ - ${checkSVCStateMaxAttempt} \ - ${checkSVCInterval} - - # expose https for cluster if e2e ssl is not set up. - if [[ "${enableCustomSSL,,}" != "true" ]]; then - kubectl apply -f ${clusterAppgwIngressHttpsYamlPath} - utility_validate_status "Create appgw ingress https svc." - utility_waitfor_ingress_completed \ - ${clusterIngressHttpsName} \ - ${wlsDomainNS} \ - ${checkSVCStateMaxAttempt} \ - ${checkSVCInterval} - fi + ${clusterIngressHttpsName} \ + ${wlsDomainNS} \ + ${checkSVCStateMaxAttempt} \ + ${checkSVCInterval} + fi } function appgw_ingress_svc_for_admin_server() { - generate_appgw_admin_config_file - kubectl apply -f ${adminAppgwIngressYamlPath} - utility_validate_status "Create appgw ingress svc." - utility_waitfor_lb_svc_completed \ - ${adminIngressName} \ - ${wlsDomainNS} \ - ${checkSVCStateMaxAttempt} \ - ${checkSVCInterval} + generate_appgw_admin_config_file + kubectl apply -f ${adminAppgwIngressYamlPath} + utility_validate_status "Create appgw ingress svc." + utility_waitfor_ingress_completed \ + ${adminIngressName} \ + ${wlsDomainNS} \ + ${checkSVCStateMaxAttempt} \ + ${checkSVCInterval} } function appgw_ingress_svc_for_remote_console() { - adminRemoteIngressName=${wlsDomainUID}-admin-remote-appgw-ingress-svc - adminRemoteAppgwIngressYamlPath=${scriptDir}/appgw-admin-remote-ingress-svc.yaml - generate_appgw_admin_remote_config_file - - kubectl apply -f ${adminRemoteAppgwIngressYamlPath} - utility_validate_status "Create appgw ingress svc." - utility_waitfor_lb_svc_completed \ - ${adminRemoteIngressName} \ - ${wlsDomainNS} \ - ${checkSVCStateMaxAttempt} \ - ${checkSVCInterval} + adminRemoteIngressName=${WLS_DOMAIN_UID}-admin-remote-appgw-ingress-svc + adminRemoteAppgwIngressYamlPath=${scriptDir}/appgw-admin-remote-ingress-svc.yaml + generate_appgw_admin_remote_config_file + + kubectl apply -f ${adminRemoteAppgwIngressYamlPath} + utility_validate_status "Create appgw ingress svc." + utility_waitfor_ingress_completed \ + ${adminRemoteIngressName} \ + ${wlsDomainNS} \ + ${checkSVCStateMaxAttempt} \ + ${checkSVCInterval} } function create_dns_record() { - if [[ "${enableCustomDNSAlias,,}" == "true" ]]; then - create_dns_CNAME_record \ - ${appgwAlias} \ - ${dnsClusterLabel} \ - ${dnsRGName} \ - ${dnsZoneName} - fi - - if [[ "${enableCustomDNSAlias,,}" == "true" ]] && - [[ "${appgwForAdminServer,,}" == "true" ]]; then - create_dns_CNAME_record \ - ${appgwAlias} \ - ${dnsAdminLabel} \ - ${dnsRGName} \ - ${dnsZoneName} - fi + if [[ "${ENABLE_DNS_CONFIGURATION,,}" == "true" ]]; then + create_dns_CNAME_record \ + ${APPGW_ALIAS} \ + ${DNS_CLUSTER_LABEL} \ + ${DNS_ZONE_RG_NAME} \ + ${DNS_ZONE_NAME} + fi + + if [[ "${ENABLE_DNS_CONFIGURATION,,}" == "true" ]] && + [[ "${APPGW_FOR_ADMIN_SERVER,,}" == "true" ]]; then + create_dns_CNAME_record \ + ${APPGW_ALIAS} \ + ${DNS_ADMIN_LABEL} \ + ${DNS_ZONE_RG_NAME} \ + ${DNS_ZONE_NAME} + fi } function create_gateway_ingress() { - # query admin server port used for non-ssl or ssl - query_admin_target_port - # query cluster port used for non-ssl or ssl - query_cluster_target_port - # create network peers between gateway vnet and aks vnet - network_peers_aks_appgw - # install azure ingress controllor - install_azure_ingress - # create tsl/ssl frontend secrets - output_create_gateway_ssl_k8s_secret - - # validate backend CA certificate - # the certificate has been upload to Application Gateway in - # weblogic-azure-aks\src\main\bicep\modules\networking.bicep - if [[ "${enableCustomSSL,,}" == "true" ]]; then - validate_backend_ca_cert - fi - - # create ingress svc for cluster - appgw_ingress_svc_for_cluster - - # create ingress svc for admin console - if [[ "${appgwForAdminServer,,}" == "true" ]]; then - appgw_ingress_svc_for_admin_server - fi - - # create ingress svc for admin remote console - if [[ "${enableRemoteConsole,,}" == "true" ]]; then - appgw_ingress_svc_for_remote_console - fi - - create_dns_record + # query admin server port used for non-ssl or ssl + query_admin_target_port + # query cluster port used for non-ssl or ssl + query_cluster_target_port + # create network peers between gateway vnet and aks vnet + network_peers_aks_appgw + + # create ingress svc for cluster + appgw_ingress_svc_for_cluster + + # create ingress svc for admin console + if [[ "${APPGW_FOR_ADMIN_SERVER,,}" == "true" ]]; then + appgw_ingress_svc_for_admin_server + fi + + # create ingress svc for admin remote console + if [[ "${APPGW_FOR_REMOTE_CONSOLE,,}" == "true" ]]; then + appgw_ingress_svc_for_remote_console + fi + + create_dns_record } # Initialize @@ -597,43 +550,13 @@ source ${scriptDir}/common.sh source ${scriptDir}/utility.sh source ${scriptDir}/createDnsRecord.sh -aksClusterRGName=$1 -aksClusterName=$2 -wlsDomainUID=$3 -subID=$4 -curRGName=$5 -appgwName=$6 -vnetName=$7 -appgwForAdminServer=$8 -enableCustomDNSAlias=$9 -dnsRGName=${10} -dnsZoneName=${11} -dnsAdminLabel=${12} -dnsClusterLabel=${13} -appgwAlias=${14} -appgwFrontendSSLCertData=${15} -appgwCertificateOption=${16} -enableCustomSSL=${17} -enableCookieBasedAffinity=${18} -enableRemoteConsole=${19} +set -Eo pipefail adminServerName=${constAdminServerName} # define in common.sh -appgwIngressHelmRepo="https://appgwingress.blob.core.windows.net/ingress-azure-helm-package/" -appgwFrontCertFileName="appgw-frontend-cert.pfx" -appgwFrontCertKeyDecrytedFileName="appgw-frontend-cert.key" -appgwFrontCertKeyFileName="appgw-frontend-cert-decryted.key" -appgwFrontPublicCertFileName="appgw-frontend-cert.crt" -appgwFrontendSecretName="frontend-tls" -appgwBackendSecretName="backend-tls" -appgwSelfsignedCert="generateCert" -azureAppgwIngressVersion="1.4.0" +azureAppgwIngressVersion="1.5.1" clusterName=${constClusterName} -httpsListenerName="myHttpsListenerName$(date +%s)" -httpsRuleName="myHttpsRule$(date +%s)" -svcAdminServer="${wlsDomainUID}-${adminServerName}" -svcCluster="${wlsDomainUID}-cluster-${clusterName}" -wlsDomainNS="${wlsDomainUID}-ns" - -read_sensitive_parameters_from_stdin +svcAdminServer="${WLS_DOMAIN_UID}-${adminServerName}" +svcCluster="${WLS_DOMAIN_UID}-cluster-${clusterName}" +wlsDomainNS="${WLS_DOMAIN_UID}-ns" create_gateway_ingress diff --git a/weblogic-azure-aks/src/main/arm/scripts/createLbSvc.sh b/weblogic-azure-aks/src/main/arm/scripts/createLbSvc.sh index 7f22943c4..bb58a6c07 100644 --- a/weblogic-azure-aks/src/main/arm/scripts/createLbSvc.sh +++ b/weblogic-azure-aks/src/main/arm/scripts/createLbSvc.sh @@ -1,4 +1,4 @@ -# Copyright (c) 2021, Oracle Corporation and/or its affiliates. +# Copyright (c) 2021, 2024, Oracle Corporation and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. # Description: to create Load Balancer Service for the following targets. @@ -8,7 +8,7 @@ # * [Optional] cluster T3 channel # # Special parameter example: -# * lbSvcValues: [{"colName":"admin-t3","colTarget":"adminServerT3","colPort":"7005"},{"colName":"cluster","colTarget":"cluster1T3","colPort":"8011"}] +# * LB_SVC_VALUES: [{"colName":"admin-t3","colTarget":"adminServerT3","colPort":"7005"},{"colName":"cluster","colTarget":"cluster1T3","colPort":"8011"}] echo "Script ${0} starts" @@ -19,10 +19,14 @@ kind: Service metadata: name: ${adminServerLBSVCName} namespace: ${wlsDomainNS} + labels: + weblogic.domainUID: "${WLS_DOMAIN_UID}" + azure.weblogic.target: "${constAdminServerName}" + azure.weblogc.createdByWlsOffer: "true" EOF # to create internal load balancer service - if [[ "${enableInternalLB,,}" == "true" ]]; then + if [[ "${USE_INTERNAL_LB,,}" == "true" ]]; then cat <>${scriptDir}/admin-server-lb.yaml annotations: service.beta.kubernetes.io/azure-load-balancer-internal: "true" @@ -37,7 +41,7 @@ spec: protocol: TCP targetPort: ${adminTargetPort} selector: - weblogic.domainUID: ${wlsDomainUID} + weblogic.domainUID: ${WLS_DOMAIN_UID} weblogic.serverName: ${adminServerName} sessionAffinity: None type: LoadBalancer @@ -51,10 +55,14 @@ kind: Service metadata: name: ${adminServerT3LBSVCName} namespace: ${wlsDomainNS} + labels: + weblogic.domainUID: "${WLS_DOMAIN_UID}" + azure.weblogic.target: "${constAdminServerName}-t3-channel" + azure.weblogc.createdByWlsOffer: "true" EOF # to create internal load balancer service - if [[ "${enableInternalLB,,}" == "true" ]]; then + if [[ "${USE_INTERNAL_LB,,}" == "true" ]]; then cat <>${adminServerT3LBDefinitionPath} annotations: service.beta.kubernetes.io/azure-load-balancer-internal: "true" @@ -69,7 +77,7 @@ spec: protocol: TCP targetPort: ${adminT3Port} selector: - weblogic.domainUID: ${wlsDomainUID} + weblogic.domainUID: ${WLS_DOMAIN_UID} weblogic.serverName: ${adminServerName} sessionAffinity: None type: LoadBalancer @@ -83,10 +91,14 @@ kind: Service metadata: name: ${clusterLBSVCName} namespace: ${wlsDomainNS} + labels: + weblogic.domainUID: "${WLS_DOMAIN_UID}" + azure.weblogic.target: "${constClusterName}" + azure.weblogc.createdByWlsOffer: "true" EOF # to create internal load balancer service - if [[ "${enableInternalLB,,}" == "true" ]]; then + if [[ "${USE_INTERNAL_LB,,}" == "true" ]]; then cat <>${scriptDir}/cluster-lb.yaml annotations: service.beta.kubernetes.io/azure-load-balancer-internal: "true" @@ -101,7 +113,7 @@ spec: protocol: TCP targetPort: ${clusterTargetPort} selector: - weblogic.domainUID: ${wlsDomainUID} + weblogic.domainUID: ${WLS_DOMAIN_UID} weblogic.clusterName: ${clusterName} sessionAffinity: None type: LoadBalancer @@ -115,10 +127,14 @@ kind: Service metadata: name: ${clusterT3LBSVCName} namespace: ${wlsDomainNS} + labels: + weblogic.domainUID: "${WLS_DOMAIN_UID}" + azure.weblogic.target: "${constClusterName}-t3-channel" + azure.weblogc.createdByWlsOffer: "true" EOF # to create internal load balancer service - if [[ "${enableInternalLB,,}" == "true" ]]; then + if [[ "${USE_INTERNAL_LB,,}" == "true" ]]; then cat <>${clusterT3LBDefinitionPath} annotations: service.beta.kubernetes.io/azure-load-balancer-internal: "true" @@ -133,7 +149,7 @@ spec: protocol: TCP targetPort: ${clusterT3Port} selector: - weblogic.domainUID: ${wlsDomainUID} + weblogic.domainUID: ${WLS_DOMAIN_UID} weblogic.clusterName: ${clusterName} sessionAffinity: None type: LoadBalancer @@ -141,17 +157,17 @@ EOF } function query_admin_target_port() { - if [[ "${enableCustomSSL,,}" == "true" ]]; then - adminTargetPort=$(utility_query_service_port ${svcAdminServer} ${wlsDomainNS} 'default-secure') + if [[ "${ENABLE_CUSTOM_SSL,,}" == "true" ]]; then + adminTargetPort=$(utility_query_service_port ${svcAdminServer} ${wlsDomainNS} 'internal-t3s') else - adminTargetPort=$(utility_query_service_port ${svcAdminServer} ${wlsDomainNS} 'default') + adminTargetPort=$(utility_query_service_port ${svcAdminServer} ${wlsDomainNS} 'internal-t3') fi echo "Admin port of ${adminServerName}: ${adminTargetPort}" } function query_cluster_target_port() { - if [[ "${enableCustomSSL,,}" == "true" ]]; then + if [[ "${ENABLE_CUSTOM_SSL,,}" == "true" ]]; then clusterTargetPort=$(utility_query_service_port ${svcCluster} ${wlsDomainNS} 'default-secure') else clusterTargetPort=$(utility_query_service_port ${svcCluster} ${wlsDomainNS} 'default') @@ -181,9 +197,9 @@ function create_lb_svc_for_admin_server_default_channel() { adminServerEndpoint=$(kubectl get svc ${adminServerLBSVCName} -n ${wlsDomainNS} \ -o=jsonpath='{.status.loadBalancer.ingress[0].ip}:{.spec.ports[0].port}') - if [ "${enableCustomDNSAlias,,}" == "true" ]; then - create_dns_A_record "${adminServerEndpoint%%:*}" ${dnsAdminLabel} ${dnsRGName} ${dnsZoneName} - adminServerEndpoint="${dnsAdminLabel}.${dnsZoneName}:${adminServerEndpoint#*:}" + if [ "${ENABLE_DNS_CONFIGURATION,,}" == "true" ]; then + create_dns_A_record "${adminServerEndpoint%%:*}" ${DNS_ADMIN_LABEL} ${DNS_ZONE_RG_NAME} ${DNS_ZONE_NAME} + adminServerEndpoint="${DNS_ADMIN_LABEL}.${DNS_ZONE_NAME}:${adminServerEndpoint#*:}" fi adminConsoleEndpoint="${adminServerEndpoint}/console" @@ -210,9 +226,9 @@ function create_lb_svc_for_admin_t3_channel() { adminServerT3Endpoint=$(kubectl get svc ${adminServerT3LBSVCName} -n ${wlsDomainNS} \ -o=jsonpath='{.status.loadBalancer.ingress[0].ip}:{.spec.ports[0].port}') - if [ "${enableCustomDNSAlias,,}" == "true" ]; then - create_dns_A_record "${adminServerT3Endpoint%%:*}" "${dnszoneAdminT3ChannelLabel}" ${dnsRGName} ${dnsZoneName} - adminServerT3Endpoint="${dnszoneAdminT3ChannelLabel}.${dnsZoneName}:${adminServerT3Endpoint#*:}" + if [ "${ENABLE_DNS_CONFIGURATION,,}" == "true" ]; then + create_dns_A_record "${adminServerT3Endpoint%%:*}" "${DNS_ADMIN_T3_LABEL}" ${DNS_ZONE_RG_NAME} ${DNS_ZONE_NAME} + adminServerT3Endpoint="${DNS_ADMIN_T3_LABEL}.${DNS_ZONE_NAME}:${adminServerT3Endpoint#*:}" fi } @@ -234,9 +250,9 @@ function create_lb_svc_for_cluster_default_channel() { clusterEndpoint=$(kubectl get svc ${clusterLBSVCName} -n ${wlsDomainNS} -o=jsonpath='{.status.loadBalancer.ingress[0].ip}:{.spec.ports[0].port}') - if [ "${enableCustomDNSAlias,,}" == "true" ]; then - create_dns_A_record "${clusterEndpoint%%:*}" ${dnsClusterLabel} ${dnsRGName} ${dnsZoneName} - clusterEndpoint="${dnsClusterLabel}.${dnsZoneName}:${clusterEndpoint#*:}" + if [ "${ENABLE_DNS_CONFIGURATION,,}" == "true" ]; then + create_dns_A_record "${clusterEndpoint%%:*}" ${DNS_CLUSTER_LABEL} ${DNS_ZONE_RG_NAME} ${DNS_ZONE_NAME} + clusterEndpoint="${DNS_CLUSTER_LABEL}.${DNS_ZONE_NAME}:${clusterEndpoint#*:}" fi } @@ -260,16 +276,16 @@ function create_lb_svc_for_cluster_t3_channel() { clusterT3Endpoint=$(kubectl get svc ${clusterT3LBSVCName} -n ${wlsDomainNS} \ -o=jsonpath='{.status.loadBalancer.ingress[0].ip}:{.spec.ports[0].port}') - if [ "${enableCustomDNSAlias,,}" == "true" ]; then - create_dns_A_record "${clusterT3Endpoint%%:*}" ${dnszoneClusterT3ChannelLabel} ${dnsRGName} ${dnsZoneName} - clusterT3Endpoint="${dnszoneClusterT3ChannelLabel}.${dnsZoneName}:${clusterT3Endpoint#*:}" + if [ "${ENABLE_DNS_CONFIGURATION,,}" == "true" ]; then + create_dns_A_record "${clusterT3Endpoint%%:*}" ${DNS_CLUSTER_T3_LABEL} ${DNS_ZONE_RG_NAME} ${DNS_ZONE_NAME} + clusterT3Endpoint="${DNS_CLUSTER_T3_LABEL}.${DNS_ZONE_NAME}:${clusterT3Endpoint#*:}" fi } function patch_admin_t3_public_address() { # patch admin t3 public address - if [ "${enableCustomDNSAlias,,}" == "true" ]; then - adminT3Address="${dnszoneAdminT3ChannelLabel}.${dnsZoneName}" + if [ "${ENABLE_DNS_CONFIGURATION,,}" == "true" ]; then + adminT3Address="${DNS_ADMIN_T3_LABEL}.${DNS_ZONE_NAME}" else adminT3Address=$(kubectl -n ${wlsDomainNS} get svc ${adminServerT3LBSVCName} -o json | jq '. | .status.loadBalancer.ingress[0].ip' | @@ -289,8 +305,8 @@ function patch_admin_t3_public_address() { function patch_cluster_t3_public_address() { #patch cluster t3 pubilc address - if [ "${enableCustomDNSAlias,,}" == "true" ]; then - clusterT3Adress="${dnszoneClusterT3ChannelLabel}.${dnsZoneName}" + if [ "${ENABLE_DNS_CONFIGURATION,,}" == "true" ]; then + clusterT3Adress="${DNS_CLUSTER_T3_LABEL}.${DNS_ZONE_NAME}" else clusterT3Adress=$(kubectl -n ${wlsDomainNS} get svc ${clusterT3LBSVCName} -o json | jq '. | .status.loadBalancer.ingress[0].ip' | @@ -310,7 +326,7 @@ function patch_cluster_t3_public_address() { function rolling_update_with_t3_public_address() { timestampBeforePatchingDomain=$(date +%s) - currentDomainConfig=$(kubectl -n ${wlsDomainNS} get domain ${wlsDomainUID} -o json) + currentDomainConfig=$(kubectl -n ${wlsDomainNS} get domain ${WLS_DOMAIN_UID} -o json) cat <${scriptDir}/domainPreviousConfiguration.yaml ${currentDomainConfig} EOF @@ -326,7 +342,7 @@ EOF if [[ "${enableClusterT3Channel,,}" == "true" ]] || [[ "${enableAdminT3Channel,,}" == "true" ]]; then # restart cluster - restartVersion=$(kubectl -n ${wlsDomainNS} get domain ${wlsDomainUID} -o json | + restartVersion=$(kubectl -n ${wlsDomainNS} get domain ${WLS_DOMAIN_UID} -o json | jq '. | .spec.restartVersion' | tr -d "\"") restartVersion=$((restartVersion + 1)) @@ -343,14 +359,15 @@ ${currentDomainConfig} EOF echo ${currentDomainConfig} | kubectl -n ${wlsDomainNS} apply -f - - replicas=$(kubectl -n ${wlsDomainNS} get domain ${wlsDomainUID} -o json | - jq '. | .spec.clusters[] | .replicas') + local clusterName=$(kubectl get cluster -n ${wlsDomainNS} -o json | jq -r '.items[0].metadata.name') + local replicas=$(kubectl -n ${wlsDomainNS} get cluster ${clusterName} -o json \ + | jq '. | .spec.replicas') # wait for the restart completed. utility_wait_for_pod_restarted \ ${timestampBeforePatchingDomain} \ ${replicas} \ - ${wlsDomainUID} \ + ${WLS_DOMAIN_UID} \ ${checkPodStatusMaxAttemps} \ ${checkPodStatusInterval} @@ -373,10 +390,10 @@ function validate_admin_console_url() { fi adminTargetPort=$(kubectl get svc ${svcAdminServer} -n ${wlsDomainNS} -o json | - jq '.spec.ports[] | select(.name=="default") | .port') + jq '.spec.ports[] | select(.name=="internal-t3") | .port') local adminConsoleUrl="http://${svcAdminServer}.${wlsDomainNS}:${adminTargetPort}/console/" - kubectl exec -it ${podName} -n ${wlsDomainNS} -c ${wlsContainerName} \ + kubectl exec ${podName} -n ${wlsDomainNS} -c ${wlsContainerName} \ -- bash -c 'curl --write-out "%{http_code}\n" --silent --output /dev/null "'${adminConsoleUrl}'" | grep "302"' if [ $? == 1 ]; then @@ -412,17 +429,8 @@ function create_svc_lb() { query_admin_target_port query_cluster_target_port - # Parse lb svc input values - # Generate valid json - ret=$(echo $lbSvcValues | sed "s/\:/\\\"\:\\\"/g" | - sed "s/{/{\"/g" | - sed "s/}/\"}/g" | - sed "s/,/\",\"/g" | - sed "s/}\",\"{/},{/g" | - tr -d \(\)) - cat <${scriptDir}/lbConfiguration.json -${ret} +${LB_SVC_VALUES} EOF array=$(jq -r '.[] | "\(.colName),\(.colTarget),\(.colPort)"' ${scriptDir}/lbConfiguration.json) @@ -477,18 +485,6 @@ source ${scriptDir}/common.sh source ${scriptDir}/utility.sh source ${scriptDir}/createDnsRecord.sh -enableInternalLB=$1 -enableCustomSSL=$2 -enableCustomDNSAlias=$3 -dnsRGName=$4 -dnsZoneName=$5 -dnsAdminLabel=$6 -dnszoneAdminT3ChannelLabel=$7 -dnsClusterLabel=$8 -dnszoneClusterT3ChannelLabel=$9 -lbSvcValues=${10} -wlsDomainUID=${11} - adminConsoleEndpoint="null" adminServerName=${constAdminServerName} # define in common.sh adminServerT3Endpoint="null" @@ -496,11 +492,11 @@ adminRemoteEndpoint="null" clusterEndpoint="null" clusterName=${constClusterName} clusterT3Endpoint="null" -svcAdminServer="${wlsDomainUID}-${adminServerName}" -svcCluster="${wlsDomainUID}-cluster-${clusterName}" -wlsDomainNS="${wlsDomainUID}-ns" +svcAdminServer="${WLS_DOMAIN_UID}-${adminServerName}" +svcCluster="${WLS_DOMAIN_UID}-cluster-${clusterName}" +wlsDomainNS="${WLS_DOMAIN_UID}-ns" -echo ${lbSvcValues} +echo ${LB_SVC_VALUES} create_svc_lb diff --git a/weblogic-azure-aks/src/main/arm/scripts/createVMAndBuildImage.sh b/weblogic-azure-aks/src/main/arm/scripts/createVMAndBuildImage.sh index 51aa393db..8f1820887 100644 --- a/weblogic-azure-aks/src/main/arm/scripts/createVMAndBuildImage.sh +++ b/weblogic-azure-aks/src/main/arm/scripts/createVMAndBuildImage.sh @@ -1,65 +1,99 @@ # Copyright (c) 2021, Oracle Corporation and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +# env inputs: +# URL_3RD_DATASOURCE +# ORACLE_ACCOUNT_ENTITLED -# read and from stdin +echo "Script ${0} starts" + +# read from stdin function read_sensitive_parameters_from_stdin() { - read azureACRPassword ocrSSOPSW + read acrShibboleth } function cleanup_vm() { + echo "deleting vm resources..." #Remove VM resources az extension add --name resource-graph # query vm id vmId=$(az graph query -q "Resources \ | where type =~ 'microsoft.compute/virtualmachines' \ | where name=~ '${vmName}' \ -| where resourceGroup =~ '${currentResourceGroup}' \ -| project vmid = id" -o tsv) +| where resourceGroup =~ '${CURRENT_RESOURCEGROUP_NAME}' \ +| project vmid = id" --query "data[0].vmid" -o tsv) # query nic id nicId=$(az graph query -q "Resources \ | where type =~ 'microsoft.compute/virtualmachines' \ | where name=~ '${vmName}' \ -| where resourceGroup =~ '${currentResourceGroup}' \ +| where resourceGroup =~ '${CURRENT_RESOURCEGROUP_NAME}' \ | extend nics=array_length(properties.networkProfile.networkInterfaces) \ | mv-expand nic=properties.networkProfile.networkInterfaces \ | where nics == 1 or nic.properties.primary =~ 'true' or isempty(nic) \ -| project nicId = tostring(nic.id)" -o tsv) - - # query ip id - ipId=$(az graph query -q "Resources \ -| where type =~ 'microsoft.network/networkinterfaces' \ -| where id=~ '${nicId}' \ -| extend ipConfigsCount=array_length(properties.ipConfigurations) \ -| mv-expand ipconfig=properties.ipConfigurations \ -| where ipConfigsCount == 1 or ipconfig.properties.primary =~ 'true' \ -| project publicIpId = tostring(ipconfig.properties.publicIPAddress.id)" -o tsv) +| project nicId = tostring(nic.id)" --query "data[0].nicId" -o tsv) # query os disk id osDiskId=$(az graph query -q "Resources \ | where type =~ 'microsoft.compute/virtualmachines' \ | where name=~ '${vmName}' \ -| where resourceGroup =~ '${currentResourceGroup}' \ -| project osDiskId = tostring(properties.storageProfile.osDisk.managedDisk.id)" -o tsv) +| where resourceGroup =~ '${CURRENT_RESOURCEGROUP_NAME}' \ +| project osDiskId = tostring(properties.storageProfile.osDisk.managedDisk.id)" --query "data[0].osDiskId" -o tsv) # query vnet id vnetId=$(az graph query -q "Resources \ | where type =~ 'Microsoft.Network/virtualNetworks' \ | where name=~ '${vmName}VNET' \ -| where resourceGroup =~ '${currentResourceGroup}' \ -| project vNetId = id" -o tsv) +| where resourceGroup =~ '${CURRENT_RESOURCEGROUP_NAME}' \ +| project vNetId = id" --query "data[0].vNetId" -o tsv) # query nsg id nsgId=$(az graph query -q "Resources \ | where type =~ 'Microsoft.Network/networkSecurityGroups' \ | where name=~ '${vmName}NSG' \ -| where resourceGroup =~ '${currentResourceGroup}' \ -| project nsgId = id" -o tsv) +| where resourceGroup =~ '${CURRENT_RESOURCEGROUP_NAME}' \ +| project nsgId = id" --query "data[0].nsgId" -o tsv) + + #query public ip id + publicIpId=$(az graph query -q "Resources \ +| where type =~ 'Microsoft.Network/publicIPAddresses' \ +| where name =~ '${vmName}PublicIP' \ +| where resourceGroup =~ '${CURRENT_RESOURCEGROUP_NAME}' \ +| project publicIpId = id" --query "data[0].publicIpId" -o tsv) # Delete VM NIC IP VNET NSG resoruces - vmResourceIdS=$(echo ${vmId} ${nicId} ${ipId} ${osDiskId} ${vnetId} ${nsgId}) - echo ${vmResourceIdS} - az resource delete --verbose --ids ${vmResourceIdS} + echo "deleting vm ${vmId}" + az vm delete --ids $vmId --yes + echo "deleting nic ${nicId}" + az network nic delete --ids ${nicId} + echo "deleting public ip ${publicIpId}" + az network public-ip delete --ids $publicIpId + echo "deleting disk ${osDiskId}" + az disk delete --yes --ids ${osDiskId} + echo "deleting vnet ${vnetId}" + az network vnet delete --ids ${vnetId} + echo "deleting nsg ${nsgId}" + az network nsg delete --ids ${nsgId} +} + +# generate image full path based on the oracle account +function get_ocr_image_full_path() { + local ocrImageFullPath="${ocrLoginServer}/${ocrGaImagePath}:${WLS_IMAGE_TAG}" + + if [[ "${ORACLE_ACCOUNT_ENTITLED,,}" == "true" ]]; then + + # download the ga cpu image mapping file. + local cpuImagesListFile=weblogic_cpu_images.json + curl -L ${gitUrl4CpuImages} --retry ${retryMaxAttempt} -o ${cpuImagesListFile} + local cpuTag=$(cat ${cpuImagesListFile} | jq ".items[] | select(.gaTag==\"${WLS_IMAGE_TAG}\") | .cpuTag" | tr -d "\"") + # if we can not find a matched image, keep the tag name the same as GA tag. + if [[ "${cpuTag}" == "" || "${cpuTag,,}" == "null" ]]; then + cpuTag=${WLS_IMAGE_TAG} + fi + + ocrImageFullPath="${ocrLoginServer}/${ocrCpuImagePath}:${cpuTag}" + fi + + wlsImagePath=${ocrImageFullPath} } # Build docker image @@ -71,55 +105,83 @@ function build_docker_image() { # Create vm to build docker image vmName="VM-UBUNTU-WLS-AKS-$(date +%s)" + # az vm image list --publisher Canonical --offer 0001-com-ubuntu-server-focal --all -o table + ubuntuImage="Canonical:ubuntu-24_04-lts:server:latest" + + if [[ "${CPU_PLATFORM}" == "${constARM64Platform}" ]]; then + ubuntuImage="Canonical:ubuntu-24_04-lts:server-arm64:latest" + fi + + # query AKS vm size + # use the same VM size to create the Ubuntu machine, make sure the architecture is matched. + local vmSize=$(az aks show --name ${AKS_CLUSTER_NAME} --resource-group ${AKS_CLUSTER_RESOURCEGROUP_NAME} \ + | jq '.agentPoolProfiles[] | select(.name=="'${AKS_NODE_POOL_NAME}'") | .vmSize' \ + | tr -d "\"") + + # if vmSize is empty or null, exit + if [[ "${vmSize}" == "" || "${vmSize}" == "null" ]]; then + echo_stderr "Failed to obtain VM size of AKS ${AKS_CLUSTER_NAME} in ${AKS_CLUSTER_RESOURCEGROUP_NAME}." + exit 1 + fi + + echo_stdout "TAG_VM: ${TAG_VM}" + export TAG_VM=$(echo "${TAG_VM}" \ + | jq -r 'to_entries | map("\"" + .key + "\"=" + (if .value|type == "string" then "\"\(.value)\"" else "\(.value)" end)) | join(" ")') + + publicIPName="${vmName}PublicIP" + # MICROSOFT_INTERNAL # Specify tag 'SkipASMAzSecPack' to skip policy 'linuxazuresecuritypackautodeployiaas_1.6' # Specify tag 'SkipNRMS*' to skip Microsoft internal NRMS policy, which causes vm-redeployed issue az vm create \ - --resource-group ${currentResourceGroup} \ + --resource-group ${CURRENT_RESOURCEGROUP_NAME} \ --name ${vmName} \ - --image "Canonical:UbuntuServer:18.04-LTS:latest" \ + --image "${ubuntuImage}" \ --admin-username azureuser \ --generate-ssh-keys \ --nsg-rule NONE \ --enable-agent true \ --vnet-name ${vmName}VNET \ --enable-auto-update false \ - --tags SkipASMAzSecPack=true SkipNRMSCorp=true SkipNRMSDatabricks=true SkipNRMSDB=true SkipNRMSHigh=true SkipNRMSMedium=true SkipNRMSRDPSSH=true SkipNRMSSAW=true SkipNRMSMgmt=true --verbose - - wlsImagePath="${ocrLoginServer}/middleware/weblogic:${wlsImageTag}" + --public-ip-address ${publicIPName} \ + --size ${vmSize} \ + --tags ${TAG_VM} SkipASMAzSecPack=true SkipNRMSCorp=true SkipNRMSDatabricks=true SkipNRMSDB=true SkipNRMSHigh=true SkipNRMSMedium=true SkipNRMSRDPSSH=true SkipNRMSSAW=true SkipNRMSMgmt=true --verbose + + if [[ "${USE_ORACLE_IMAGE,,}" == "${constTrue}" ]]; then + get_ocr_image_full_path + else + wlsImagePath="${USER_PROVIDED_IMAGE_PATH}" + fi + + echo_stdout "wlsImagePath: ${wlsImagePath}" + URL_3RD_DATASOURCE=$(echo $URL_3RD_DATASOURCE | tr -d "\"") # remove " from the string + URL_3RD_DATASOURCE=$(echo $URL_3RD_DATASOURCE | base64 -w0) + # Tag for VM extension is not supported yet, see https://github.com/Azure/azure-cli/issues/14341 az vm extension set --name CustomScript \ - --extension-instance-name wls-image-script \ - --resource-group ${currentResourceGroup} \ - --vm-name ${vmName} \ - --publisher Microsoft.Azure.Extensions \ - --version 2.0 \ - --settings "{ \"fileUris\": [\"${scriptURL}model.properties\",\"${scriptURL}genImageModel.sh\",\"${scriptURL}buildWLSDockerImage.sh\",\"${scriptURL}common.sh\"]}" \ - --protected-settings "{\"commandToExecute\":\"echo ${azureACRPassword} ${ocrSSOPSW} | bash buildWLSDockerImage.sh ${wlsImagePath} ${azureACRServer} ${azureACRUserName} ${newImageTag} \\\"${appPackageUrls}\\\" ${ocrSSOUser} ${wlsClusterSize} ${enableCustomSSL} ${enableAdminT3Tunneling} ${enableClusterT3Tunneling} \"}" + --extension-instance-name wls-image-script \ + --resource-group ${CURRENT_RESOURCEGROUP_NAME} \ + --vm-name ${vmName} \ + --publisher Microsoft.Azure.Extensions \ + --version 2.0 \ + --settings "{ \"fileUris\": [\"${SCRIPT_LOCATION}model.properties\",\"${SCRIPT_LOCATION}genImageModel.sh\",\"${SCRIPT_LOCATION}buildWLSDockerImage.sh\",\"${SCRIPT_LOCATION}common.sh\"]}" \ + --protected-settings "{\"commandToExecute\":\"echo ${acrShibboleth} ${ORACLE_ACCOUNT_SHIBBOLETH} | bash buildWLSDockerImage.sh ${wlsImagePath} ${acrLoginServer} ${acrUser} ${newImageTag} ${WLS_APP_PACKAGE_URLS} ${ORACLE_ACCOUNT_NAME} ${WLS_CLUSTER_SIZE} ${ENABLE_CUSTOM_SSL} ${ENABLE_ADMIN_CUSTOM_T3} ${ENABLE_CLUSTER_CUSTOM_T3} ${USE_ORACLE_IMAGE} ${URL_3RD_DATASOURCE} ${ENABLE_SHIBBOLETHLESS_DB_CONNECTION} ${DB_TYPE} ${CPU_PLATFORM} \"}" cleanup_vm } # Shell Global settings -set -e #Exit immediately if a command exits with a non-zero status. +set -Eeo pipefail #Exit immediately if a command exits with a non-zero status. # Main script export script="${BASH_SOURCE[0]}" export scriptDir="$(cd "$(dirname "${script}")" && pwd)" source ${scriptDir}/common.sh +source ${scriptDir}/utility.sh -export currentResourceGroup=$1 -export wlsImageTag=$2 -export azureACRServer=$3 -export azureACRUserName=$4 -export newImageTag=$5 -export appPackageUrls=$6 -export ocrSSOUser=$7 -export wlsClusterSize=$8 -export enableCustomSSL=$9 -export scriptURL=${10} -export enableAdminT3Tunneling=${11} -export enableClusterT3Tunneling=${12} +export newImageTag=$1 +export acrLoginServer=$2 +export acrUser=$3 read_sensitive_parameters_from_stdin diff --git a/weblogic-azure-aks/src/main/arm/scripts/dbUtility.sh b/weblogic-azure-aks/src/main/arm/scripts/dbUtility.sh index 9bc9c86ff..23a65d7b8 100644 --- a/weblogic-azure-aks/src/main/arm/scripts/dbUtility.sh +++ b/weblogic-azure-aks/src/main/arm/scripts/dbUtility.sh @@ -3,20 +3,25 @@ echo "Script ${0} starts" -# read from stdin -function read_sensitive_parameters_from_stdin() { - read dbPassword -} - function generate_ds_model() { databaseDriver=${driverOracle} databaseTestTableName=${testTableOracle} - if [[ "${databaseType}" == "${dbTypePostgre}" ]]; then + if [[ "${DATABASE_TYPE}" == "${dbTypePostgre}" ]]; then databaseDriver=${driverPostgre} databaseTestTableName=${testTablePostgre} - elif [[ "${databaseType}" == "${dbTypeSQLServer}" ]]; then + elif [[ "${DATABASE_TYPE}" == "${dbTypeSQLServer}" ]]; then databaseDriver=${driverSQLServer} databaseTestTableName=${testTableSQLServer} + elif [[ "${DATABASE_TYPE}" == "${dbTypeMySQL}" ]]; then + databaseDriver=${driverMySQL} + databaseTestTableName=${testTableMySQL} + + if [[ "${ENABLE_SHIBBOLETHLESS_CONNECTION,,}" == "true" ]]; then + databaseDriver=${driverMySQLCj} + fi + elif [[ "${DATABASE_TYPE}" == "${dbTypeOthers}" ]]; then + databaseDriver=${DB_DRIVER_NAME} + databaseTestTableName=${TEST_TABLE_NAME} fi echo "generate data source model file" @@ -24,7 +29,7 @@ function generate_ds_model() { dsModelFilePath=$scriptDir/${dbSecretName}.yaml bash $scriptDir/genDatasourceModel.sh \ ${dsModelFilePath} \ - "${jdbcDataSourceName}" \ + "${JDBC_DATASOURCE_NAME}" \ "${clusterName}" \ "${databaseDriver}" \ "${databaseTestTableName}" \ @@ -68,11 +73,11 @@ function export_models_and_delete_configmap() { function cleanup_secret_and_model() { echo "check if the datasource secret exists" - jndiLabel=${jdbcDataSourceName//\//\_} + jndiLabel=${JDBC_DATASOURCE_NAME//\//\_} secretLen=$(kubectl get secret -n ${domainNamespace} -l datasource.JNDI="${jndiLabel}" -o json | jq '.items | length') if [ ${secretLen} -ge 1 ]; then - echo "secret for ${jdbcDataSourceName} exists" + echo "secret for ${JDBC_DATASOURCE_NAME} exists" # delete the secrets index=0 while [ $index -lt ${secretLen} ]; do @@ -93,16 +98,16 @@ function cleanup_secret_and_model() { function create_datasource_secret() { cleanup_secret_and_model - echo "create/update secret ${dbSecretName} for ${jdbcDataSourceName}" + echo "create/update secret ${dbSecretName} for ${JDBC_DATASOURCE_NAME}" kubectl -n ${domainNamespace} create secret generic \ ${dbSecretName} \ - --from-literal=password="${dbPassword}" \ - --from-literal=url="${dsConnectionURL}" \ - --from-literal=user="${dbUser}" + --from-literal=password="${DB_SHIBBOLETH}" \ + --from-literal=url="${DB_CONNECTION_STRING}" \ + --from-literal=user="${DB_USER}" kubectl -n sample-domain1-ns label secret \ ${dbSecretName} \ - weblogic.domainUID=${wlsDomainUID} \ + weblogic.domainUID=${WLS_DOMAIN_UID} \ datasource.JNDI="${jndiLabel}" } @@ -118,7 +123,7 @@ function update_configmap() { kubectl -n ${domainNamespace} create configmap ${wlsConfigmapName} \ --from-file=${modelFilePath} kubectl -n ${domainNamespace} label configmap ${wlsConfigmapName} \ - weblogic.domainUID=${wlsDomainUID} + weblogic.domainUID=${WLS_DOMAIN_UID} } function delete_model_and_secret() { @@ -132,36 +137,36 @@ function delete_model_and_secret() { kubectl -n ${domainNamespace} create configmap ${wlsConfigmapName} \ --from-file=${modelFilePath} kubectl -n ${domainNamespace} label configmap ${wlsConfigmapName} \ - weblogic.domainUID=${wlsDomainUID} + weblogic.domainUID=${WLS_DOMAIN_UID} } # Main script +set -Eo pipefail + export script="${BASH_SOURCE[0]}" export scriptDir="$(cd "$(dirname "${script}")" && pwd)" -export databaseType=$1 -export dbUser=$2 -export dsConnectionURL=$3 -export jdbcDataSourceName=$4 -export wlsDomainUID=$5 -export dbSecretName=$6 -export operationType=$7 +export dbSecretName=$1 +export operationType=$2 -export domainNamespace=${wlsDomainUID}-ns +export domainNamespace=${WLS_DOMAIN_UID}-ns export clusterName="cluster-1" export dbTypeOracle="oracle" export dbTypePostgre="postgresql" export dbTypeSQLServer="sqlserver" +export dbTypeMySQL='mysql' +export dbTypeOthers="otherdb" export driverOracle="oracle.jdbc.OracleDriver" export driverPostgre="org.postgresql.Driver" export driverSQLServer="com.microsoft.sqlserver.jdbc.SQLServerDriver" +export driverMySQL="com.mysql.jdbc.Driver" +export driverMySQLCj="com.mysql.cj.jdbc.Driver" export optTypeDelete='delete' export testTableOracle="SQL ISVALID" export testTablePostgre="SQL SELECT 1" export testTableSQLServer="SQL SELECT 1" -export wlsConfigmapName="${wlsDomainUID}-wdt-config-map" - -read_sensitive_parameters_from_stdin +export testTableMySQL="SQL SELECT 1" +export wlsConfigmapName="${WLS_DOMAIN_UID}-wdt-config-map" if [[ "${operationType}" == "${optTypeDelete}" ]]; then delete_model_and_secret diff --git a/weblogic-azure-aks/src/main/arm/scripts/genDatasourceModel.sh b/weblogic-azure-aks/src/main/arm/scripts/genDatasourceModel.sh index 19c9543e7..ec7e5ad0e 100644 --- a/weblogic-azure-aks/src/main/arm/scripts/genDatasourceModel.sh +++ b/weblogic-azure-aks/src/main/arm/scripts/genDatasourceModel.sh @@ -25,7 +25,7 @@ resources: JNDIName: [ ${jndiName} ] - GlobalTransactionsProtocol: TwoPhaseCommit + GlobalTransactionsProtocol: ${GLOBAL_TRANSATION_PROTOCOL} JDBCDriverParams: DriverName: ${driver} URL: '@@SECRET:${secretName}:url@@' diff --git a/weblogic-azure-aks/src/main/arm/scripts/genDomainConfig.sh b/weblogic-azure-aks/src/main/arm/scripts/genDomainConfig.sh index d4072b1d4..5636f9a05 100644 --- a/weblogic-azure-aks/src/main/arm/scripts/genDomainConfig.sh +++ b/weblogic-azure-aks/src/main/arm/scripts/genDomainConfig.sh @@ -5,24 +5,25 @@ export script="${BASH_SOURCE[0]}" export scriptDir="$(cd "$(dirname "${script}")" && pwd)" export filePath=$1 -export replicas=$2 -export wlsCPU=$3 -export wlsDomainUID=$4 -export wlsDomainName=$5 -export wlsImagePath=$6 -export wlsMemory=$7 -export wlsManagedPrefix=$8 -export enableSSL=${9} -export enablePV=${10} -export enableAdminT3Tunneling=${11} -export enableClusterT3Tunneling=${12} -export t3AdminPort=${13} -export t3ClusterPort=${14} -export clusterName=${15} -export javaOptions=${16} - -export adminServiceUrl="${wlsDomainUID}-admin-server.${wlsDomainUID}-ns.svc.cluster.local" -export clusterServiceUrl="${wlsDomainUID}-cluster-${clusterName}.${wlsDomainUID}-ns.svc.cluster.local" +export wlsImagePath=$2 +export javaOptions=$3 + +export adminServiceUrl="${WLS_DOMAIN_UID}-admin-server.${WLS_DOMAIN_UID}-ns.svc.cluster.local" +export clusterServiceUrl="${WLS_DOMAIN_UID}-cluster-${constClusterName}.${WLS_DOMAIN_UID}-ns.svc.cluster.local" + +# set classpath +preClassPath="" +classPath="/u01/domains/${WLS_DOMAIN_UID}/wlsdeploy/${externalJDBCLibrariesDirectoryName}/*" + +if [[ "${DB_TYPE}" == "mysql" ]]; then + preClassPath="/u01/domains/${WLS_DOMAIN_UID}/wlsdeploy/${constPreclassDirectoryName}/*:" +fi + +if [[ "${ENABLE_SHIBBOLETHLESS_DB_CONNECTION,,}" == "true" ]] && [[ "${DB_TYPE}" == "mysql" || "${DB_TYPE}" == "postgresql" ]]; then + # append jackson libraries to pre-classpath to upgrade existing libs in GA images + preClassPath="${preClassPath}/u01/domains/${WLS_DOMAIN_UID}/wlsdeploy/classpathLibraries/jackson/*" + classPath="${classPath}:/u01/domains/${WLS_DOMAIN_UID}/wlsdeploy/classpathLibraries/azureLibraries/*" +fi cat <$filePath # Copyright (c) 2021, Oracle Corporation and/or its affiliates. @@ -32,13 +33,13 @@ cat <$filePath # in https://github.com/oracle/weblogic-kubernetes-operator. # This is an example of how to define a Domain resource. # -apiVersion: "weblogic.oracle/v8" +apiVersion: "weblogic.oracle/v9" kind: Domain metadata: - name: "${wlsDomainUID}" - namespace: "${wlsDomainUID}-ns" + name: "${WLS_DOMAIN_UID}" + namespace: "${WLS_DOMAIN_UID}-ns" labels: - weblogic.domainUID: "${wlsDomainUID}" + weblogic.domainUID: "${WLS_DOMAIN_UID}" spec: # Set to 'FromModel' to indicate 'Model in Image'. @@ -46,9 +47,9 @@ spec: # The WebLogic Domain Home, this must be a location within # the image for 'Model in Image' domains. - domainHome: /u01/domains/${wlsDomainUID} + domainHome: /u01/domains/${WLS_DOMAIN_UID} - # The WebLogic Server Docker image that the Operator uses to start the domain + # The WebLogic Server image that the Operator uses to start the domain image: "${wlsImagePath}" # Defaults to "Always" if image tag (version) is ':latest' @@ -61,7 +62,7 @@ spec: # Identify which Secret contains the WebLogic Admin credentials, # the secret must contain 'username' and 'password' fields. webLogicCredentialsSecret: - name: "${wlsDomainUID}-weblogic-credentials" + name: "${WLS_DOMAIN_UID}-weblogic-credentials" # Whether to include the WebLogic Server stdout in the pod's stdout, default is true includeServerOutInPodLog: true @@ -71,88 +72,102 @@ spec: # The location for domain log, server logs, server out, introspector out, and Node Manager log files # see also 'logHomeEnabled', 'volumes', and 'volumeMounts'. - #logHome: /shared/logs/${wlsDomainUID} + #logHome: /shared/logs/${WLS_DOMAIN_UID} # Set which WebLogic Servers the Operator will start - # - "NEVER" will not start any server in the domain - # - "ADMIN_ONLY" will start up only the administration server (no managed servers will be started) - # - "IF_NEEDED" will start all non-clustered servers, including the administration server, and clustered servers up to their replica count. - serverStartPolicy: "IF_NEEDED" + # - "Never" will not start any server in the domain + # - "AdminOnly" will start up only the administration server (no managed servers will be started) + # - "IfNeeded" will start all non-clustered servers, including the administration server, and clustered servers up to their replica count. + serverStartPolicy: IfNeeded # Settings for all server pods in the domain including the introspector job pod serverPod: + # Tune for small VM sizes + # https://oracle.github.io/weblogic-kubernetes-operator/managing-domains/domain-lifecycle/liveness-readiness-probe-customization/ + livenessProbe: + periodSeconds: ${constLivenessProbePeriodSeconds} + timeoutSeconds: ${constLivenessProbeTimeoutSeconds} + failureThreshold: ${constLivenessProbeFailureThreshold} + readinessProbe: + periodSeconds: ${constReadinessProbeProbePeriodSeconds} + timeoutSeconds: ${constReadinessProbeTimeoutSeconds} + failureThreshold: ${constReadinessProbeFailureThreshold} # Optional new or overridden environment variables for the domain's pods # - This sample uses CUSTOM_DOMAIN_NAME in its image model file # to set the Weblogic domain name env: - name: CUSTOM_DOMAIN_NAME - value: "${wlsDomainName}" + value: "${WLS_DOMAIN_NAME}" - name: JAVA_OPTIONS - value: "-Dweblogic.StdoutDebugEnabled=false ${javaOptions}" + value: "${constDefaultJavaOptions} ${javaOptions}" - name: USER_MEM_ARGS - value: "-Djava.security.egd=file:/dev/./urandom -Xms256m -Xmx512m -XX:MinRAMPercentage=25.0 -XX:MaxRAMPercentage=50.0 " + value: "${constDefaultJVMArgs}" - name: MANAGED_SERVER_PREFIX - value: "${wlsManagedPrefix}" + value: "${WLS_MANAGED_SERVER_PREFIX}" + - name: PRE_CLASSPATH + value: "${preClassPath}" + - name: CLASSPATH + value: "${classPath}" EOF -if [[ "${enableSSL,,}" == "true" ]]; then - cat <>$filePath +if [[ "${ENABLE_CUSTOM_SSL,,}" == "true" ]]; then + cat <>$filePath - name: SSL_IDENTITY_PRIVATE_KEY_ALIAS valueFrom: secretKeyRef: key: sslidentitykeyalias - name: ${wlsDomainUID}-weblogic-ssl-credentials + name: ${WLS_DOMAIN_UID}-weblogic-ssl-credentials - name: SSL_IDENTITY_PRIVATE_KEY_PSW valueFrom: secretKeyRef: key: sslidentitykeypassword - name: ${wlsDomainUID}-weblogic-ssl-credentials + name: ${WLS_DOMAIN_UID}-weblogic-ssl-credentials - name: SSL_IDENTITY_PRIVATE_KEYSTORE_PATH valueFrom: secretKeyRef: key: sslidentitystorepath - name: ${wlsDomainUID}-weblogic-ssl-credentials + name: ${WLS_DOMAIN_UID}-weblogic-ssl-credentials - name: SSL_IDENTITY_PRIVATE_KEYSTORE_TYPE valueFrom: secretKeyRef: key: sslidentitystoretype - name: ${wlsDomainUID}-weblogic-ssl-credentials + name: ${WLS_DOMAIN_UID}-weblogic-ssl-credentials - name: SSL_IDENTITY_PRIVATE_KEYSTORE_PSW valueFrom: secretKeyRef: key: sslidentitystorepassword - name: ${wlsDomainUID}-weblogic-ssl-credentials + name: ${WLS_DOMAIN_UID}-weblogic-ssl-credentials - name: SSL_TRUST_KEYSTORE_PATH valueFrom: secretKeyRef: key: ssltruststorepath - name: ${wlsDomainUID}-weblogic-ssl-credentials + name: ${WLS_DOMAIN_UID}-weblogic-ssl-credentials - name: SSL_TRUST_KEYSTORE_TYPE valueFrom: secretKeyRef: key: ssltruststoretype - name: ${wlsDomainUID}-weblogic-ssl-credentials + name: ${WLS_DOMAIN_UID}-weblogic-ssl-credentials - name: SSL_TRUST_KEYSTORE_PSW valueFrom: secretKeyRef: key: ssltruststorepassword - name: ${wlsDomainUID}-weblogic-ssl-credentials + name: ${WLS_DOMAIN_UID}-weblogic-ssl-credentials EOF - fi +fi -if [[ "${enableAdminT3Tunneling,,}" == "true" ]]; then +if [[ "${ENABLE_ADMIN_CUSTOM_T3,,}" == "true" ]]; then cat <>$filePath - name: T3_TUNNELING_ADMIN_PORT - value: "${t3AdminPort}" + value: "${WLS_T3_ADMIN_PORT}" - name: T3_TUNNELING_ADMIN_ADDRESS value: "${adminServiceUrl}" EOF fi -if [[ "${enableClusterT3Tunneling,,}" == "true" ]]; then +if [[ "${ENABLE_CLUSTER_CUSTOM_T3,,}" == "true" ]]; then cat <>$filePath - name: T3_TUNNELING_CLUSTER_PORT - value: "${t3ClusterPort}" + value: "${WLS_T3_CLUSTER_PORT}" - name: T3_TUNNELING_CLUSTER_ADDRESS value: "${clusterServiceUrl}" EOF @@ -162,30 +177,34 @@ fi cat <>$filePath resources: requests: - cpu: "${wlsCPU}" - memory: "${wlsMemory}" + cpu: "${WLS_RESOURCE_REQUEST_CPU}" + memory: "${WLS_RESOURCE_REQUEST_MEMORY}" EOF -if [[ "${enablePV,,}" == "true" ]]; then +# enable db pod identity, all of the selector of pod identities are "db-pod-idenity" +if [[ "${ENABLE_SHIBBOLETHLESS_DB_CONNECTION,,}" == "true" ]]; then + cat <>$filePath + labels: + aadpodidbinding: "${constDbPodIdentitySelector}" +EOF +fi + +if [[ "${ENABLE_PV,,}" == "true" ]]; then cat <>$filePath # Optional volumes and mounts for the domain's pods. See also 'logHome'. volumes: - - name: ${wlsDomainUID}-pv-azurefile + - name: ${WLS_DOMAIN_UID}-pv-azurefile persistentVolumeClaim: - claimName: ${wlsDomainUID}-pvc-azurefile + claimName: ${WLS_DOMAIN_UID}-pvc-azurefile volumeMounts: - mountPath: /shared - name: ${wlsDomainUID}-pv-azurefile + name: ${WLS_DOMAIN_UID}-pv-azurefile EOF fi cat <>$filePath # The desired behavior for starting the domain's administration server. adminServer: - # The serverStartState legal values are "RUNNING" or "ADMIN" - # "RUNNING" means the listed server will be started up to "RUNNING" mode - # "ADMIN" means the listed server will be start up to "ADMIN" mode - serverStartState: "RUNNING" # Setup a Kubernetes node port for the administration server default channel #adminService: # channels: @@ -195,27 +214,9 @@ cat <>$filePath # The number of admin servers to start for unlisted clusters replicas: 1 - # The desired behavior for starting a specific cluster's member servers + # The name of each Cluster resource clusters: - - clusterName: cluster-1 - serverStartState: "RUNNING" - serverPod: - # Instructs Kubernetes scheduler to prefer nodes for new cluster members where there are not - # already members of the same cluster. - affinity: - podAntiAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 100 - podAffinityTerm: - labelSelector: - matchExpressions: - - key: "weblogic.clusterName" - operator: In - values: - - \$(CLUSTER_NAME) - topologyKey: "kubernetes.io/hostname" - # The number of managed servers to start for unlisted clusters - replicas: ${replicas} + - name: ${WLS_DOMAIN_UID}-cluster-1 # Change the restartVersion to force the introspector job to rerun # and apply any new model configuration, to also force a subsequent @@ -230,13 +231,31 @@ cat <>$filePath domainType: "WLS" # Optional configmap for additional models and variable files - #configMap: ${wlsDomainUID}-wdt-config-map + #configMap: ${WLS_DOMAIN_UID}-wdt-config-map # All 'FromModel' domains require a runtimeEncryptionSecret with a 'password' field - runtimeEncryptionSecret: "${wlsDomainUID}-runtime-encryption-secret" + runtimeEncryptionSecret: "${WLS_DOMAIN_UID}-runtime-encryption-secret" # Secrets that are referenced by model yaml macros # (the model yaml in the optional configMap or in the image) #secrets: - #- ${wlsDomainUID}-datasource-secret -EOF \ No newline at end of file + #- ${WLS_DOMAIN_UID}-datasource-secret + +--- + +apiVersion: "weblogic.oracle/v1" +kind: Cluster +metadata: + name: ${WLS_DOMAIN_UID}-cluster-1 + # Update this with the namespace your domain will run in: + namespace: ${WLS_DOMAIN_UID}-ns + labels: + # Update this with the domainUID of your domain: + weblogic.domainUID: ${WLS_DOMAIN_UID} +spec: + # This must match a cluster name that is specified in the WebLogic configuration + clusterName: cluster-1 + # The number of managed servers to start for this cluster + replicas: 2 + +EOF diff --git a/weblogic-azure-aks/src/main/arm/scripts/genImageModel.sh b/weblogic-azure-aks/src/main/arm/scripts/genImageModel.sh index 5daf9dad9..106bd86a3 100644 --- a/weblogic-azure-aks/src/main/arm/scripts/genImageModel.sh +++ b/weblogic-azure-aks/src/main/arm/scripts/genImageModel.sh @@ -33,7 +33,6 @@ domainInfo: AdminUserName: "@@SECRET:__weblogic-credentials__:username@@" AdminPassword: "@@SECRET:__weblogic-credentials__:password@@" ServerStartMode: "prod" - domainLibraries: [ 'wlsdeploy/domainLibraries/postgresql-42.2.8.jar', 'wlsdeploy/domainLibraries/mssql-jdbc-7.4.1.jre8.jar'] topology: Name: "@@ENV:CUSTOM_DOMAIN_NAME@@" @@ -136,7 +135,9 @@ cat <>${filePath} SecurityConfiguration: NodeManagerUsername: "@@SECRET:__weblogic-credentials__:username@@" NodeManagerPasswordEncrypted: "@@SECRET:__weblogic-credentials__:password@@" - + SecureMode: + SecureModeEnabled: false + resources: SelfTuning: MinThreadsConstraint: @@ -169,6 +170,7 @@ EOF index=1 for item in $appUrlArray; do echo ${item} + item=$(echo $item | tr -d "\"") # remove "" # e.g. https://wlsaksapp.blob.core.windows.net/japps/testwebapp.war?sp=r&se=2021-04-29T15:12:38Z&sv=2020-02-10&sr=b&sig=7grL4qP%2BcJ%2BLfDJgHXiDeQ2ZvlWosRLRQ1ciLk0Kl7M%3D urlWithoutQueryString="${item%\?*}" echo $urlWithoutQueryString @@ -183,7 +185,7 @@ EOF continue fi - curl -m ${curlMaxTime} -fL "$item" -o ${scriptDir}/model-images/wlsdeploy/applications/${fileName} + curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -fL "$item" -o ${scriptDir}/model-images/wlsdeploy/applications/${fileName} if [ $? -ne 0 ];then echo "Failed to download $item" exit 1 @@ -198,4 +200,4 @@ EOF done # print model -cat ${filePath} \ No newline at end of file +cat ${filePath} diff --git a/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/enableAgic.sh b/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/enableAgic.sh new file mode 100644 index 000000000..2660d9d2b --- /dev/null +++ b/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/enableAgic.sh @@ -0,0 +1,44 @@ +# Copyright (c) 2021, 2024, Oracle Corporation and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +function enable_aks_msi() { + local identityLength=$(az aks show -g ${AKS_CLUSTER_RG_NAME} -n ${AKS_CLUSTER_NAME} | jq '.identity | length') + echo "identityLength ${identityLength}" + + if [ $identityLength -lt 1 ]; then + echo "enable managed identity..." + # Your cluster is using service principal, and you are going to update the cluster to use systemassigned managed identity. + # After updating, your cluster's control plane and addon pods will switch to use managed identity, but kubelet will KEEP USING SERVICE PRINCIPAL until you upgrade your agentpool. + az aks update -y -g ${AKS_CLUSTER_RG_NAME} -n ${AKS_CLUSTER_NAME} --enable-managed-identity + + utility_validate_status "Enable managed identity for ${AKS_CLUSTER_NAME}." + fi +} + +function install_azure_ingress() { + local agicEnabled=$(az aks show -n ${AKS_CLUSTER_NAME} -g ${AKS_CLUSTER_RG_NAME} | + jq '.addonProfiles.ingressApplicationGateway.enabled') + local agicGatewayId="" + + if [[ "${agicEnabled,,}" == "true" ]]; then + agicGatewayId=$(az aks show -n ${AKS_CLUSTER_NAME} -g ${AKS_CLUSTER_RG_NAME} | + jq '.addonProfiles.ingressApplicationGateway.config.applicationGatewayId' | + tr -d "\"") + fi + + local appgwId=$(az network application-gateway show \ + -n ${APPGW_NAME} \ + -g ${CURRENT_RG_NAME} -o tsv --query "id") + + if [[ "${agicGatewayId}" != "${appgwId}" ]]; then + az aks enable-addons -n ${AKS_CLUSTER_NAME} -g ${AKS_CLUSTER_RG_NAME} --addons ingress-appgw --appgw-id $appgwId + utility_validate_status "Install app gateway ingress controller." + fi +} + +# Main script +set -Eo pipefail + +enable_aks_msi + +install_azure_ingress diff --git a/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/enableHpa.sh b/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/enableHpa.sh new file mode 100644 index 000000000..36524bae5 --- /dev/null +++ b/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/enableHpa.sh @@ -0,0 +1,68 @@ +# Copyright (c) 2024, Oracle Corporation and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +function get_cluster_uid(){ + local clusterUid=$(kubectl get clusters -n ${WLS_NAMESPACE} -o=jsonpath='{.items[].metadata.name}') + utility_validate_status "Obtain cluster UID." + export WLS_CLUSTER_UID=${clusterUid} +} + +function scaling_basedon_cpu(){ + kubectl autoscale cluster ${WLS_CLUSTER_UID} \ + --cpu-percent=${UTILIZATION_PERCENTAGE} \ + --min=1 \ + --max=${WLS_CLUSTER_SIZE} \ + -n ${WLS_NAMESPACE} + utility_validate_status "Enable HPA based on CPU utilization." +} + +function scaling_basedon_memory(){ + cat <scaler-memory.yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: ${WLS_CLUSTER_UID} + namespace: ${WLS_NAMESPACE} +spec: + scaleTargetRef: + apiVersion: weblogic.oracle/v1 + kind: Cluster + name: ${WLS_CLUSTER_UID} + minReplicas: 1 + maxReplicas: ${WLS_CLUSTER_SIZE} + metrics: + - type: Resource + resource: + name: memory + target: + averageUtilization: ${UTILIZATION_PERCENTAGE} + type: Utilization +EOF + + kubectl apply -f scaler-memory.yaml + utility_validate_status "Enable HPA based on memory utilization." +} + +function check_kubernetes_metrics_server(){ + # $?=1 if there is no running kms pod. + kubectl get pod -l k8s-app=metrics-server -n kube-system | grep "Running" + # exit if $?=1 + utility_validate_status "There should be at least one pod of kubernetes metrics server running." +} + +# Main script +set -Eo pipefail + +install_kubectl + +connect_aks $AKS_CLUSTER_NAME $AKS_CLUSTER_RG_NAME + +get_cluster_uid + +check_kubernetes_metrics_server + +if [ "$HPA_SCALE_TYPE" == "cpu" ]; then + scaling_basedon_cpu +elif [ "$HPA_SCALE_TYPE" == "memory" ]; then + scaling_basedon_memory +fi diff --git a/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/enablePrometheusMetrics.sh b/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/enablePrometheusMetrics.sh new file mode 100644 index 000000000..1d8917c8d --- /dev/null +++ b/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/enablePrometheusMetrics.sh @@ -0,0 +1,405 @@ +# Copyright (c) 2024, Oracle Corporation and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +#!/bin/bash + +function enable_promethues_metrics(){ + # See https://learn.microsoft.com/en-us/azure/azure-monitor/containers/kubernetes-monitoring-enable?tabs=cli#enable-prometheus-and-grafana + az extension add --name k8s-extension && true + + ### Use existing Azure Monitor workspace + az aks update --enable-azure-monitor-metrics \ + --name ${AKS_CLUSTER_NAME} \ + --resource-group ${AKS_CLUSTER_RG_NAME} \ + --azure-monitor-workspace-resource-id "${AMA_WORKSPACE_ID}" \ + --only-show-errors + + utility_validate_status "Enable Promethues Metrics." + + az extension add --name aks-preview && true + az extension remove --name k8s-extension && true + + #Verify that the DaemonSet was deployed properly on the Linux node pools + #https://learn.microsoft.com/en-us/azure/azure-monitor/containers/kubernetes-monitoring-enable?tabs=cli#managed-prometheus + kubectl get ds ama-metrics-node --namespace=kube-system + #if the deployment fails, $?=1. + utility_validate_status "Validate promethues metrics is enabled." +} + +# https://learn.microsoft.com/en-us/azure/azure-monitor/containers/prometheus-metrics-scrape-configuration +function deploy_customize_scraping(){ + # https://learn.microsoft.com/en-us/azure/azure-monitor/containers/prometheus-metrics-scrape-configuration?tabs=CRDConfig%2CCRDScrapeConfig#basic-authentication + local wlsShibbolethBase64=$(echo -n "${WLS_ADMIN_SHIBBOLETH}" | base64) + cat <prometheus-config +global: + scrape_interval: 30s +scrape_configs: +- job_name: '${WLS_DOMAIN_UID}' + kubernetes_sd_configs: + - role: pod + namespaces: + names: [${WLS_NAMESPACE}] + basic_auth: + username: ${WLS_ADMIN_USERNAME} + password_file: /etc/prometheus/certs/password1 +EOF + + #validate the scrape config file + local podNamesinKubeSystem=$(kubectl get pods -l rsName=ama-metrics -n=kube-system -o json | jq -r '.items[].metadata.name') + mkdir promconfigvalidator + for podname in ${podNamesinKubeSystem} + do + kubectl cp -n=kube-system "${podname}":/opt/promconfigvalidator ./promconfigvalidator/promconfigvalidator + kubectl cp -n=kube-system "${podname}":/opt/microsoft/otelcollector/collector-config-template.yml ./promconfigvalidator/collector-config-template.yml + chmod 500 ./promconfigvalidator/promconfigvalidator + done + + if [ ! -f "./promconfigvalidator/promconfigvalidator" ]; then + echo_stderr "Failed to download promconfigvalidator tool that is shipped inside the Azure Monitor metrics addon pod(s)." + exit 1 + fi + + ./promconfigvalidator/promconfigvalidator --config "./prometheus-config" --otelTemplate "./promconfigvalidator/collector-config-template.yml" + utility_validate_status "Validate prometheus-config using promconfigvalidator." + + kubectl create configmap ama-metrics-prometheus-config --from-file=prometheus-config -n kube-system + utility_validate_status "Create ama-metrics-prometheus-config in kube-system namespace." +} + +function get_wls_monitoring_exporter_image_url() { + local wlsToolingFamilyJsonFile=weblogic_tooling_family.json + local imageUrl="ghcr.io/oracle/weblogic-monitoring-exporter:2.1.9" + + # download the json file that has well tested monitoring exporter image url from weblogic-azure repo. + curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -fsL "${gitUrl4WLSToolingFamilyJsonFile}" -o ${wlsToolingFamilyJsonFile} + if [ $? -eq 0 ]; then + imageURL=$(cat ${wlsToolingFamilyJsonFile} | jq ".items[] | select(.key==\"WME\") | .imageURL" | tr -d "\"") + echo_stdout "well tested monitoring exporter image url: ${imageURL}" + fi + + echo_stdout "Use monitoring exporter image: ${imageURL} " + export WME_IMAGE_URL=${imageUrl} +} + +# https://github.com/oracle/weblogic-monitoring-exporter +function deploy_webLogic_monitoring_exporter(){ + local wlsVersion=$(kubectl -n ${WLS_NAMESPACE} get domain ${WLS_DOMAIN_UID} -o=jsonpath='{.spec.restartVersion}' | tr -d "\"") + wlsVersion=$((wlsVersion+1)) + + cat <patch-file.json +[ + { + "op": "replace", + "path": "/spec/restartVersion", + "value": "${wlsVersion}" + }, + { + "op": "add", + "path": "/spec/monitoringExporter", + "value": { + "configuration": { + "domainQualifier": true, + "metricsNameSnakeCase": true, + "queries": [ + { + "applicationRuntimes": { + "componentRuntimes": { + "key": "name", + "prefix": "webapp_config_", + "servlets": { + "key": "servletName", + "prefix": "weblogic_servlet_", + "values": [ + "invocationTotalCount", + "reloadTotal", + "executionTimeAverage", + "poolMaxCapacity", + "executionTimeTotal", + "reloadTotalCount", + "executionTimeHigh", + "executionTimeLow" + ] + }, + "type": "WebAppComponentRuntime", + "values": [ + "deploymentState", + "contextRoot", + "sourceInfo", + "openSessionsHighCount", + "openSessionsCurrentCount", + "sessionsOpenedTotalCount", + "sessionCookieMaxAgeSecs", + "sessionInvalidationIntervalSecs", + "sessionTimeoutSecs", + "singleThreadedServletPoolSize", + "sessionIDLength", + "servletReloadCheckSecs", + "jSPPageCheckSecs" + ] + }, + "workManagerRuntimes": { + "prefix": "workmanager_", + "key": "applicationName", + "values": [ + "pendingRequests", + "completedRequests", + "stuckThreadCount"] + }, + "key": "name", + "keyName": "app" + }, + "JVMRuntime": { + "key": "name", + "values": [ + "heapFreeCurrent", + "heapFreePercent", + "heapSizeCurrent", + "heapSizeMax", + "uptime", + "processCpuLoad" + ] + }, + "key": "name", + "keyName": "server" + } + ] + }, + "image": "${WME_IMAGE_URL}", + "port": 8080 + } + } +] +EOF + + kubectl -n ${WLS_NAMESPACE} patch domain ${WLS_DOMAIN_UID} \ + --type=json \ + --patch-file patch-file.json + utility_validate_status "Enable WebLogic Monitoring Exporter." + + local timestampBeforePatchingDomain=$(date +%s) + local clusterName=$(kubectl get cluster -n ${WLS_NAMESPACE} -o json | jq -r '.items[0].metadata.name') + local replicas=$(kubectl -n ${WLS_NAMESPACE} get cluster ${clusterName} -o json \ + | jq '. | .spec.replicas') + + # wait for the restart completed. + utility_wait_for_pod_restarted \ + ${timestampBeforePatchingDomain} \ + ${replicas} \ + ${WLS_DOMAIN_UID} \ + ${checkPodStatusMaxAttemps} \ + ${checkPodStatusInterval} +} + +function wait_for_keda_ready(){ + local ready=false + local attempt=0 + + while [[ "${ready}" == "false" && $attempt -le ${checkKedaMaxAttempt} ]]; do + echo_stdout "Check if KEDA is ready, attempt: ${attempt}." + ready=true + + local podCount=$(kubectl get pods -n ${KEDA_NAMESPACE} -o json | jq -r '.items | length') + if [ $podCount -lt 3 ];then + ready=false + fi + + local podnames=$(kubectl get pods -n ${KEDA_NAMESPACE} -o json | jq -r '.items[].metadata.name') + for podname in ${podnames} + do + kubectl get pod ${podname} -n ${KEDA_NAMESPACE} | grep "Running" + + if [ $? -eq 1 ];then + ready=false + fi + done + + attempt=$((attempt + 1)) + sleep ${checkKedaInteval} + done + + if [ ${attempt} -gt ${checkKedaMaxAttempt} ]; then + echo_stderr "Failed to enable KEDA." + exit 1 + fi + + echo_stderr "KEDA is running." +} + +function get_keda_latest_version() { + local kedaVersion + kedaVersion=$(helm search repo kedacore/keda --versions | awk '/^kedacore\/keda/ {print $2; exit}') + export KEDA_VERSION="${kedaVersion}" + echo_stderr "Use latest KEDA. KEDA version: ${KEDA_VERSION}" +} + + +function get_keda_version() { + local versionJsonFileName="aks_tooling_well_tested_version.json" + local kedaWellTestedVersion + + # Download the version JSON file + curl -L "${gitUrl4AksToolingWellTestedVersionJsonFile}" --retry "${retryMaxAttempt}" -o "${versionJsonFileName}" + + # Extract KEDA version from JSON + kedaWellTestedVersion=$(jq -r '.items[] | select(.key == "keda") | .version' "${versionJsonFileName}") + + # Check if version is available + if [ $? -ne 0 ]; then + get_keda_latest_version + return 0 + fi + + # Print KEDA well-tested version + echo_stderr "KEDA well-tested version: ${kedaWellTestedVersion}" + + # Search for KEDA version in Helm repo + if ! helm search repo kedacore/keda --versions | grep -q "${kedaWellTestedVersion}"; then + get_keda_latest_version + return 0 + fi + + # Export KEDA version + export KEDA_VERSION="${kedaWellTestedVersion}" + echo_stderr "KEDA version: ${KEDA_VERSION}" +} + +# https://learn.microsoft.com/en-us/azure/azure-monitor/containers/integrate-keda +function enable_keda_addon() { + local oidcEnabled=$(az aks show --resource-group $AKS_CLUSTER_RG_NAME --name $AKS_CLUSTER_NAME --query oidcIssuerProfile.enabled) + local workloadIdentity=$(az aks show --resource-group $AKS_CLUSTER_RG_NAME --name $AKS_CLUSTER_NAME --query securityProfile.workloadIdentity) + + if [[ "${oidcEnabled,,}" == "false" || -z "${workloadIdentity}" ]]; then + # mitigate https://github.com/Azure/azure-cli/issues/28649 + pip install --upgrade azure-core + az aks update -g $AKS_CLUSTER_RG_NAME -n $AKS_CLUSTER_NAME --enable-workload-identity --enable-oidc-issuer + utility_validate_status "Enable oidc and worload identity in AKS $AKS_CLUSTER_NAME." + fi + + export OIDC_ISSUER_URL=$(az aks show -n $AKS_CLUSTER_NAME -g $AKS_CLUSTER_RG_NAME --query "oidcIssuerProfile.issuerUrl" -otsv) + export KEDA_UAMI_CLIENT_ID=$(az identity show --resource-group $CURRENT_RG_NAME --name $KEDA_UAMI_NAME --query 'clientId' -otsv) + local tenantId=$(az identity show --resource-group $CURRENT_RG_NAME --name $KEDA_UAMI_NAME --query 'tenantId' -otsv) + + kubectl create namespace ${KEDA_NAMESPACE} + + cat <kedascalersample.yaml +apiVersion: keda.sh/v1alpha1 +kind: TriggerAuthentication +metadata: + name: azure-managed-prometheus-trigger-auth + namespace: ${WLS_NAMESPACE} +spec: + podIdentity: + provider: azure-workload + identityId: ${KEDA_UAMI_CLIENT_ID} +--- +apiVersion: keda.sh/v1alpha1 +kind: ScaledObject +metadata: + name: azure-managed-prometheus-scaler + namespace: ${WLS_NAMESPACE} +spec: + scaleTargetRef: + apiVersion: weblogic.oracle/v1 + kind: Cluster + name: ${clusterName} + minReplicaCount: 1 + maxReplicaCount: ${WLS_CLUSTER_SIZE} + triggers: + - type: prometheus + metadata: + serverAddress: ${kedaServerAddress} + metricName: webapp_config_open_sessions_high_count + query: sum(webapp_config_open_sessions_high_count{app=""}) # Note: query must return a vector/scalar single element response + threshold: '10' + activationThreshold: '1' + authenticationRef: + name: azure-managed-prometheus-trigger-auth +EOF + + local base64ofKedaScalerSample=$(cat ./kedascalersample.yaml | base64) + local result=$(jq -n -c \ + --arg kedaScalerServerAddress "$kedaServerAddress" \ + --arg base64ofKedaScalerSample "${base64ofKedaScalerSample}" \ + '{kedaScalerServerAddress: $kedaScalerServerAddress, base64ofKedaScalerSample: $base64ofKedaScalerSample}') + echo "result is: $result" + echo $result >$AZ_SCRIPTS_OUTPUT_PATH +} + +# TBD see if we can query some of the metrics + +# Main script +set -Eo pipefail + +install_kubectl + +install_helm + +connect_aks $AKS_CLUSTER_NAME $AKS_CLUSTER_RG_NAME + +get_wls_monitoring_exporter_image_url + +deploy_webLogic_monitoring_exporter + +enable_promethues_metrics + +deploy_customize_scraping + +enable_keda_addon + +output diff --git a/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/queryDomainConfigurations.sh b/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/queryDomainConfigurations.sh new file mode 100644 index 000000000..4719c0748 --- /dev/null +++ b/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/queryDomainConfigurations.sh @@ -0,0 +1,81 @@ +# Copyright (c) 2021, 2024 Oracle Corporation and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +# This script runs on Azure Container Instance with Alpine Linux that Azure Deployment script creates. +# +# env inputs: +# AKS_CLUSTER_NAME +# AKS_CLUSTER_RESOURCEGROUP_NAME +# WLS_CLUSTER_NAME +# WLS_DOMAIN_UID + +# Main script +wlsContainerName="weblogic-server" + +echo "install kubectl" +az aks install-cli + +echo "Connect AKS" +connect_aks $AKS_CLUSTER_NAME $AKS_CLUSTER_RESOURCEGROUP_NAME + +wlsDomainNS="${WLS_DOMAIN_UID}-ns" + +domainConfigurationYaml=/tmp/domain.yaml +rm -f ${domainConfigurationYaml} +kubectl get domain ${WLS_DOMAIN_UID} -n ${wlsDomainNS} -o yaml >${domainConfigurationYaml} + +podNum=$(kubectl -n ${wlsDomainNS} get pod -l weblogic.clusterName=${WLS_CLUSTER_NAME} -o json | jq '.items| length') + if [ ${podNum} -le 0 ]; then + echo_stderr "Ensure your cluster has at least one pod." + exit 1 + fi + +podName=$(kubectl -n ${wlsDomainNS} get pod -l weblogic.clusterName=${WLS_CLUSTER_NAME} -o json \ + | jq '.items[0] | .metadata.name' \ + | tr -d "\"") + +echo "Copy model.yaml from /u01/wdt/models" +targetModelYaml=/tmp/model.yaml +rm -f ${targetModelYaml} +kubectl cp -n ${wlsDomainNS} -c ${wlsContainerName} ${podName}:/u01/wdt/models/model.yaml ${targetModelYaml} +if [ $? != 0 ]; then + echo >&2 "Fail to copy ${podName}:/u01/wdt/models/model.yaml." + exit 1 +fi + +echo "Copy model.properties from from /u01/wdt/models" +targetModelProperties=/tmp/model.properties +rm -f ${targetModelProperties} +kubectl cp -n ${wlsDomainNS} -c ${wlsContainerName} ${podName}:/u01/wdt/models/model.properties ${targetModelProperties} +if [ $? != 0 ]; then + echo >&2 "Fail to copy ${podName}:/u01/wdt/models/model.properties." + exit 1 +fi + +echo "Query WebLogic version and patch numbers" +targetFile4Versions=/tmp/version.info +kubectl exec ${podName} -n ${wlsDomainNS} -c ${wlsContainerName} \ + -- bash -c 'source $ORACLE_HOME/wlserver/server/bin/setWLSEnv.sh > /dev/null 2>&1 && java weblogic.version -verbose >"'${targetFile4Versions}'"' +if [ $? != 0 ]; then + echo >&2 "Fail to run java weblogic.version." + exit 1 +fi +rm -f ${targetFile4Versions} +kubectl cp -n ${wlsDomainNS} -c ${wlsContainerName} ${podName}:${targetFile4Versions} ${targetFile4Versions} +if [ $? != 0 ]; then + echo >&2 "Fail to copy ${podName}:${targetFile4Versions}." + exit 1 +fi + +base64ofDomainYaml=$(cat ${domainConfigurationYaml} | base64) +base64ofModelYaml=$(cat ${targetModelYaml} | base64) +base64ofModelProperties=$(cat ${targetModelProperties} | base64) +base64ofWLSVersionDetails=$(cat ${targetFile4Versions} | base64) + +result=$(jq -n -c \ + --arg domainDeploymentYaml "$base64ofDomainYaml" \ + --arg wlsImageModelYaml "$base64ofModelYaml" \ + --arg wlsImageProperties "$base64ofModelProperties" \ + --arg wlsVersionDetails "${base64ofWLSVersionDetails}" \ + '{domainDeploymentYaml: $domainDeploymentYaml, wlsImageModelYaml: $wlsImageModelYaml, wlsImageProperties: $wlsImageProperties, wlsVersionDetails: $wlsVersionDetails}') +echo "result is: $result" +echo $result >$AZ_SCRIPTS_OUTPUT_PATH diff --git a/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/queryPrivateIPForAppGateway.sh b/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/queryPrivateIPForAppGateway.sh new file mode 100644 index 000000000..1db3a69c3 --- /dev/null +++ b/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/queryPrivateIPForAppGateway.sh @@ -0,0 +1,44 @@ +# Copyright (c) 2022, Oracle Corporation and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +# This script runs on Azure Container Instance with Alpine Linux that Azure Deployment script creates. +# +# env inputs: +# SUBNET_ID +# KNOWN_IP + +function query_ip() { + echo_stdout "Subnet Id: ${SUBNET_ID}" + + # select a available private IP + # azure reserves the first 3 private IPs. + local ret=$(az network vnet check-ip-address \ + --ids ${SUBNET_ID} \ + --ip-address ${KNOWN_IP}) + local available=$(echo ${ret} | jq -r .available) + if [[ "${available,,}" == "true" ]]; then + outputPrivateIP=${KNOWN_IP} + else + local privateIPAddress=$(echo ${ret} | jq -r .availableIpAddresses[0]) + if [[ -z "${privateIPAddress}" ]] || [[ "${privateIPAddress}"=="null" ]]; then + echo_stderr "ERROR: make sure there is available IP for application gateway in your subnet." + fi + + outputPrivateIP=${privateIPAddress} + fi +} + +function output_result() { + echo "Available Private IP: ${outputPrivateIP}" + result=$(jq -n -c \ + --arg privateIP "$outputPrivateIP" \ + '{privateIP: $privateIP}') + echo "result is: $result" + echo $result >$AZ_SCRIPTS_OUTPUT_PATH +} + +# main script +outputPrivateIP="10.0.0.1" + +query_ip + +output_result \ No newline at end of file diff --git a/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/validateAgic.sh b/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/validateAgic.sh new file mode 100644 index 000000000..a7756cf14 --- /dev/null +++ b/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/validateAgic.sh @@ -0,0 +1,36 @@ +# Copyright (c) 2024, Oracle Corporation and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +function wait_for_azure_ingress_ready() { + local ready=false + local attempt=0 + + while [[ "${ready}" == "false" && $attempt -le ${checkAgicMaxAttempt} ]]; do + echo_stdout "Check if ACIG is ready, attempt: ${attempt}." + ready=true + + local ret=$(kubectl get pod -n kube-system | grep "ingress-appgw-deployment-*" | grep "Running") + if [ -z "${ret}" ]; then + ready=false + fi + + attempt=$((attempt + 1)) + sleep ${checkAgicInterval} + done + + if [ ${attempt} -gt ${checkAgicMaxAttempt} ]; then + echo_stderr "Failed to enable Application Gateway Ingress Controler." + exit 1 + fi + + echo "Application Gateway Ingress Controler is running." +} + +# Main script +set -Eo pipefail + +install_kubectl + +connect_aks $AKS_CLUSTER_NAME $AKS_CLUSTER_RG_NAME + +wait_for_azure_ingress_ready diff --git a/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/validateParameters.sh b/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/validateParameters.sh new file mode 100644 index 000000000..e4460b126 --- /dev/null +++ b/weblogic-azure-aks/src/main/arm/scripts/inline-scripts/validateParameters.sh @@ -0,0 +1,588 @@ +# Copyright (c) 2021, 2024, Oracle Corporation and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +# This script runs on Azure Container Instance with Alpine Linux that Azure Deployment script creates. +# +# env inputs: +# ORACLE_ACCOUNT_NAME +# ORACLE_ACCOUNT_SHIBBOLETH +# ACR_NAME +# AKS_CLUSTER_NAME +# AKS_CLUSTER_RESOURCEGROUP_NAME +# BASE64_FOR_SERVICE_PRINCIPAL +# WLS_SSL_IDENTITY_DATA +# WLS_SSL_IDENTITY_SHIBBOLETH +# WLS_SSL_IDENTITY_TYPE +# WLS_SSL_TRUST_DATA +# WLS_SSL_TRUST_SHIBBOLETH +# WLS_SSL_TRUST_TYPE +# WLS_SSL_PRIVATE_KEY_ALIAS +# WLS_SSL_PRIVATE_KEY_SHIBBOLETH +# APPLICATION_GATEWAY_SSL_FRONTEND_CERT_DATA +# APPLICATION_GATEWAY_SSL_FRONTEND_CERT_SHIBBOLETH +# DNS_ZONE_NAME +# DNS_ZONE_RESOURCEGROUP_NAME +# AKS_VERSION +# USE_AKS_WELL_TESTED_VERSION +# VNET_FOR_APPLICATIONGATEWAY + +#Validate teminal status with $?, exit with exception if errors happen. +# $1 - error message +# $2 - root cause message +function validate_status() { + if [ $? != 0 ]; then + echo_stderr "Errors happen during: $1." $2 + exit 1 + else + echo_stdout "$1" + fi +} + +# Validate compute resources +# Check points: +# - there is enough resource for AKS cluster +# - there is enough resource for VM to build the image +# Example to list the vm usage: +# az vm list-usage --location "East US" -o table +# Name CurrentValue Limit +# ---------------------------------------- -------------- ------- +# Availability Sets 0 2500 +# Total Regional vCPUs 2 200 +# Virtual Machines 1 25000 +# Virtual Machine Scale Sets 0 2500 +# Dedicated vCPUs 0 3000 +# Cloud Services 0 2500 +# Total Regional Low-priority vCPUs 0 100 +# Standard DSv2 Family vCPUs 0 100 +# Standard Av2 Family vCPUs 2 100 +# Basic A Family vCPUs 0 100 +# Standard A0-A7 Family vCPUs 0 200 +# Standard A8-A11 Family vCPUs 0 100 +# Standard D Family vCPUs 0 100 +# Standard Dv2 Family vCPUs 0 100 +# Standard DS Family vCPUs 0 100 +# Standard G Family vCPUs 0 100 +# Standard GS Family vCPUs 0 100 +# Standard F Family vCPUs 0 100 +# Standard FS Family vCPUs 0 100 +# ... ... +function validate_compute_resources() { + # Resource for ubuntu machine + # 2 Standard Av2 Family vCPUs + + # query total cores + local vmUsage=$(az vm list-usage -l ${location} -o json) + local totalCPUs=$(echo ${vmUsage} | jq '.[] | select(.name.value=="cores") | .limit' | tr -d "\"") + local currentCPUs=$(echo ${vmUsage} | jq '.[] | select(.name.value=="cores") | .currentValue' | tr -d "\"") + local aksCPUs=0 + + # if creating new AKS cluster + if [[ "${createAKSCluster,,}" == "true" ]]; then + local aksVMDetails=$(az vm list-skus --size ${aksAgentPoolVMSize} -l ${location} --query [0]) + local vmFamily=$(echo ${aksVMDetails} | jq '.family' | tr -d "\"") + local vmCPUs=$(echo ${aksVMDetails} | jq '.capabilities[] | select(.name=="vCPUs") | .value' | tr -d "\"") + aksCPUs=$((vmCPUs * aksAgentPoolNodeCount)) + + # query CPU usage of the vm family + local familyLimit=$(echo ${vmUsage} | jq '.[] | select(.name.value=="'${vmFamily}'") | .limit' | tr -d "\"") + local familyUsage=$(echo ${vmUsage} | jq '.[] | select(.name.value=="'${vmFamily}'") | .currentValue' | tr -d "\"") + local requiredFamilyCPUs=$((aksCPUs + familyUsage)) + # make sure thers is enough vCPUs of the family for AKS + if [ ${requiredFamilyCPUs} -gt ${familyLimit} ]; then + echo_stderr "It requires ${aksCPUs} ${vmFamily} vCPUs to create the AKS cluster, ${vmFamily} vCPUs quota is limited to ${familyLimit}, current usage is ${familyUsage}." + exit 1 + fi + fi + + local vmFamilyOfUbuntu="standardAv2Family" + local familyLimit=$(echo ${vmUsage} | jq '.[] | select(.name.value=="'${vmFamilyOfUbuntu}'") | .limit' | tr -d "\"") + local familyUsage=$(echo ${vmUsage} | jq '.[] | select(.name.value=="'${vmFamilyOfUbuntu}'") | .currentValue' | tr -d "\"") + local requiredFamilyCPUs=$((2 + familyUsage)) + # make sure thers is enough vCPUs of the family for ubuntu machine + if [ ${requiredFamilyCPUs} -gt ${familyLimit} ]; then + echo_stderr "It requires 2 ${vmFamilyOfUbuntu} vCPUs to create an ubuntu machine for docker image, ${vmFamilyOfUbuntu} vCPUs quota is limited to ${familyLimit}, current usage is ${familyUsage}." + exit 1 + fi + + local requiredCPU=$((aksCPUs + 2 + currentCPUs)) + if [ ${requiredCPU} -gt ${totalCPUs} ]; then + echo_stderr "It requires ${requiredCPU} vCPUs to run WLS on AKS, vCPUs quota is limited to ${totalCPUs}, current usage is ${currentCPUs}." + exit 1 + fi + + echo_stdout "Check compute resources: passed!" +} + +# Ensure the cluster has enough memory resources. +# The offer deploys a WLS cluster with 1 + ${APP_REPLICAS} pods, each pod requestes 1.5GB and 0.25CPU. +# Minimum memory requirement: 12 + (APP_REPLICAS + 1)*1.5 GB +function validate_memory_resources() { + if [[ "${createAKSCluster,,}" == "true" ]]; then + local requiredMemoryinGB=$(echo "12+($APP_REPLICAS+1)*1.5" | bc) + + local vmDetails=$(az vm list-skus --size ${aksAgentPoolVMSize} -l ${location} --query [0]) + validate_status "Query VM details of ${aksAgentPoolVMSize} in ${location}." + + local memoryGB=$(echo ${vmDetails} | jq '.capabilities[] | select(.name=="MemoryGB") | .value' | tr -d "\"") + local requestedMemory=$(echo "$aksAgentPoolNodeCount*$memoryGB" | bc) + echo_stdout "Current requested memory is ${requestedMemory}GB." + if [[ $(echo "${requestedMemory}<${requiredMemoryinGB}" | bc) -eq 1 ]]; then + echo_stderr "It requires ${requiredMemoryinGB} GiB memory to create the AKS cluster, you have to select a larger VM size or increase node count." + exit 1 + fi + + fi + + echo_stdout "Check memory resources: passed!" +} + +function validate_ocr_account() { + # ORACLE_ACCOUNT_NAME + # ORACLE_ACCOUNT_SHIBBOLETH + docker logout + echo "${ORACLE_ACCOUNT_SHIBBOLETH}" | docker login ${ocrLoginServer} -u ${ORACLE_ACCOUNT_NAME} --password-stdin + validate_status "login OCR with user ${ORACLE_ACCOUNT_NAME}" + + echo_stdout "Check OCR account: passed!" +} + +function check_acr() { + local ready=false + local attempt=0 + while [[ "${ready}" == "false" && $attempt -le ${checkAcrMaxAttempt} ]]; do + echo_stdout "Check if ACR ${ACR_NAME} is ready, attempt: ${attempt}." + ready=true + + local ret=$(az acr show --name ${ACR_NAME} --resource-group ${ACR_RESOURCE_GROUP}) + if [ -z "${ret}" ]; then + ready=false + fi + + attempt=$((attempt + 1)) + sleep ${checkAcrInterval} + done + + if [ ${attempt} -gt ${checkAcrMaxAttempt} ]; then + echo_stderr "ACR ${ACR_NAME} is not ready." + exit 1 + fi + + echo_stdout "Check if ACR ${ACR_NAME} is ready to import image." +} + +function obtain_image_architecture() { + local acrName=$1 + local repoName=$2 + local tag=$3 + local imageUri="${acrName}.azurecr.io/${repoName}:${tag}" + + local imageArch=$(az acr manifest list-metadata -r ${acrName} -n ${repoName} \ + | jq '.[] | select(.tags != null) | select(.tags[] | length >0 ) | select(.tags[0]=="'${tag}'") | .architecture' \ + | tr -d "\"") + + if [[ "${imageArch}" == "null" ]]; then + # if the image is multi-architecture, the value is empty. + # Use the docker manifest inspect command to get the architecture. + # https://learn.microsoft.com/en-us/azure/container-registry/push-multi-architecture-images + local acrUserName=$(az acr credential show -n ${acrName} --query "username" | tr -d "\"") + local acrShibboleth=$(az acr credential show -n ${acrName} --query "passwords[0].value" | tr -d "\"") + local acrServer="${acrName}.azurecr.io" + + docker login ${acrServer} -u ${acrUserName} -p ${acrShibboleth} + local ret=$(docker manifest inspect ${imageUri} | jq '.manifests[] | .platform.architecture') + + if [[ $ret == *"${constX86Platform}"* && $ret == *"${constARM64Platform}"* ]]; then + imageArch="${constMultiArchPlatform}" + elif [[ $ret == *"${constX86Platform}"* ]]; then + imageArch="${constX86Platform}" + elif [[ $ret == *"${constARM64Platform}"* ]]; then + imageArch="${constARM64Platform}" + else + echo_stderr "The architecture of image is not supported. Currently only ARM64 and AMD64 are supported." + exit 1 + fi + fi + echo_stdout "Architecture of image is ${imageArch}." + + export IMAGE_ARCHITECTURE=${imageArch} +} + +function validate_ocr_image() { + local ocrImageFullPath="${ocrLoginServer}/${ocrGaImagePath}:${wlsImageTag}" + + if [[ "${ORACLE_ACCOUNT_ENTITLED,,}" == "true" ]]; then + + # download the ga cpu image mapping file. + local cpuImagesListFile=weblogic_cpu_images.json + curl -L "${gitUrl4CpuImages}" --retry ${retryMaxAttempt} -o ${cpuImagesListFile} + local cpuTag=$(cat ${cpuImagesListFile} | jq ".items[] | select(.gaTag == \"${wlsImageTag}\") | .cpuTag" | tr -d "\"") + echo_stdout "cpu tag: ${cpuTag}" + # if we can not find a matched image, keep the input tag. + if [[ "${cpuTag}" == "" || "${cpuTag,,}" == "null" ]]; then + cpuTag=${wlsImageTag} + fi + + ocrImageFullPath="${ocrLoginServer}/${ocrCpuImagePath}:${cpuTag}" + fi + + echo_stdout "image path: ${ocrImageFullPath}" + + # to mitigate error in https://learn.microsoft.com/en-us/answers/questions/1188413/the-resource-with-name-name-and-type-microsoft-con + az provider register -n Microsoft.ContainerRegistry + + check_acr + + # validate the image by importing it to ACR. + # if failure happens, the image should be unavailable + local tmpRepo="tmp$(date +%s)" + local tmpImagePath="${tmpRepo}:${wlsImageTag}" + az acr import --name ${ACR_NAME} \ + --resource-group ${ACR_RESOURCE_GROUP} \ + --source ${ocrImageFullPath} \ + -u ${ORACLE_ACCOUNT_NAME} \ + -p ${ORACLE_ACCOUNT_SHIBBOLETH} \ + --image ${tmpImagePath} \ + --only-show-errors + + # $? equals 0 even though failure happens. + # check if the image is imported successfully. + local ret=$(az acr repository show --name $ACR_NAME --image ${tmpImagePath}) + if [ -n "${ret}" ]; then + obtain_image_architecture ${ACR_NAME} ${tmpRepo} ${wlsImageTag} + # delete the image from ACR. + az acr repository delete --name ${ACR_NAME} --image ${tmpImagePath} --yes + else + echo_stderr $ret + echo_stderr "" + echo_stderr "Image ${ocrImageFullPath} is not available! Please make sure you have accepted the Oracle Standard Terms and Restrictions and the image exists in https://container-registry.oracle.com/ " + if [[ "${ORACLE_ACCOUNT_ENTITLED,,}" == "true" ]]; then + echo_stderr "Make sure you are entitled to access middleware/weblogic_cpu repository." + fi + + exit 1 + fi + + echo_stdout "Check OCR image ${ocrImageFullPath}: passed!" +} + +function check_acr_admin_enabled() { + local acrName=$1 + local acrRgName=$2 + echo_stdout "check if admin user enabled in ACR $acrName " + local adminUserEnabled=$(az acr show --name $acrName --resource-group ${acrRgName} --query "adminUserEnabled") + validate_status "query 'adminUserEnabled' property of ACR ${acrName}" "Invalid ACR: ${acrName}" + + if [[ "${adminUserEnabled}" == "false" ]]; then + echo_stderr "Make sure admin user is enabled in ACR $acrName. Please find steps in https://docs.microsoft.com/en-us/azure/container-registry/container-registry-authentication?WT.mc_id=Portal-Microsoft_Azure_CreateUIDef&tabs=azure-cli#admin-account" + exit 1 + fi +} + +function validate_acr_image() { + echo_stdout "user provided ACR: $ACR_NAME_FOR_USER_PROVIDED_IMAGE" + + local pathWithoutTag=${userProvidedImagePath%\:*} + local repository=${pathWithoutTag#*\/} + local tag="${userProvidedImagePath##*:}" + + local tagIndex=$(az acr repository show-tags --name $ACR_NAME_FOR_USER_PROVIDED_IMAGE --repository ${repository} | jq 'index("'${tag}'")') + validate_status "check if tag ${tag} exists." "Invalid image path ${userProvidedImagePath}" + if [[ "${tagIndex}" == "null" ]]; then + echo_stderr "Image ${tag} does not exist in ${repository}." + exit 1 + fi + + obtain_image_architecture ${ACR_NAME_FOR_USER_PROVIDED_IMAGE} ${repository} ${tag} + + echo_stdout "Check ACR image: passed!" +} + +function validate_base_image_path() { + if [[ "${useOracleImage,,}" == "true" ]]; then + validate_ocr_account + validate_ocr_image + else + validate_acr_image + fi +} + +function validate_acr_admin_enabled() +{ + if [[ "${useOracleImage,,}" == "true" ]]; then + check_acr_admin_enabled "${ACR_NAME}" "${ACR_RESOURCE_GROUP}" + else + check_acr_admin_enabled "${ACR_NAME_FOR_USER_PROVIDED_IMAGE}" "${ACR_RG_NAME_FOR_USER_PROVIDED_IMAGE}" + fi +} + +# Validate whether image architecture is matched with the architecture of the VM. +# Azure supports both AMD based processor and ARM based CPU, see https://learn.microsoft.com/en-us/azure/virtual-machines/vm-naming-conventions. + # For ARM cpu, the VM size name includes letter 'p'. + # For AMD cpu, the VM size name does not include letter 'p'. +# Validate cases: + # 1. If the VM size is AMD based, the image should be amd64 or multi-platform. + # 2. If the VM size is ARM based, the image should be arm64 or multi-platform. +# IMAGE_ARCHITECTURE value may be "amd64", "arm64" or "Multi-architecture (amd64 and arm64)". +function validate_image_compatibility +{ + if [[ $aksAgentPoolVMSize == *"p"* ]]; then + if [[ "${IMAGE_ARCHITECTURE}" != "${constARM64Platform}" && "${IMAGE_ARCHITECTURE}" != "${constMultiArchPlatform}" ]]; then + echo_stderr "The image architecture ${IMAGE_ARCHITECTURE} is not compatible with the ARM based VM size ${aksAgentPoolVMSize}." + exit 1 + fi + else + if [[ "${IMAGE_ARCHITECTURE}" != "${constX86Platform}" && "${IMAGE_ARCHITECTURE}" != "${constMultiArchPlatform}" ]]; then + echo_stderr "The image architecture ${IMAGE_ARCHITECTURE} is not compatible with the AMD based VM size ${aksAgentPoolVMSize}." + exit 1 + fi + fi +} + +function validate_wls_ssl_certificates() { + local wlsIdentityKeyStoreFileName=${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/identity.keystore + local wlsTrustKeyStoreFileName=${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/trust.keystore + echo "$WLS_SSL_IDENTITY_DATA" | base64 -d >$wlsIdentityKeyStoreFileName + echo "$WLS_SSL_TRUST_DATA" | base64 -d >$wlsTrustKeyStoreFileName + + # use default Java, if no, install open jdk 11. + # why not using Microsoft open jdk? + # No apk installation package! + export JAVA_HOME=/usr/lib/jvm/default-jvm/ + if [ ! -d "${JAVA_HOME}" ]; then + install_jdk + JAVA_HOME=/usr/lib/jvm/java-11-openjdk + fi + #validate if identity keystore has entry + ${JAVA_HOME}/bin/keytool -list -v \ + -keystore $wlsIdentityKeyStoreFileName \ + -storepass $WLS_SSL_IDENTITY_SHIBBOLETH \ + -storetype $WLS_SSL_IDENTITY_TYPE | + grep 'Entry type:' | + grep 'PrivateKeyEntry' + + validate_status "validate Identity Keystore." + + #validate if trust keystore has entry + ${JAVA_HOME}/bin/keytool -list -v \ + -keystore ${wlsTrustKeyStoreFileName} \ + -storepass $WLS_SSL_TRUST_SHIBBOLETH \ + -storetype $WLS_SSL_TRUST_TYPE | + grep 'Entry type:' | + grep 'trustedCertEntry' + + validate_status "validate Trust Keystore." + + echo_stdout "validate SSL key stores: passed!" +} + +function validate_gateway_frontend_certificates() { + if [[ "${appGatewayCertificateOption}" == "generateCert" ]]; then + return + fi + + local appgwFrontCertFileName=${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/gatewaycert.pfx + echo "$APPLICATION_GATEWAY_SSL_FRONTEND_CERT_DATA" | base64 -d >$appgwFrontCertFileName + + openssl pkcs12 \ + -in $appgwFrontCertFileName \ + -nocerts \ + -out ${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/cert.key \ + -passin pass:${APPLICATION_GATEWAY_SSL_FRONTEND_CERT_SHIBBOLETH} \ + -passout pass:${APPLICATION_GATEWAY_SSL_FRONTEND_CERT_SHIBBOLETH} + + validate_status "access application gateway frontend key." "Make sure the Application Gateway frontend certificate is correct." +} + +function validate_dns_zone() { + if [[ "${checkDNSZone,,}" == "true" ]]; then + az network dns zone show -n ${DNS_ZONE_NAME} -g ${DNS_ZONE_RESOURCEGROUP_NAME} + validate_status "check DNS Zone ${DNS_ZONE_NAME}" "Make sure the DNS Zone exists." + + echo_stdout "Check DNS Zone: passed!" + fi +} + +function get_aks_default_version() { + constDefaultAKSVersion=$(az aks get-versions --location ${location} \ + | jq '.orchestrators[] | select(.default==true) | .orchestratorVersion' \ + | tr -d "\"") + + validate_status "get AKS default version ${constDefaultAKSVersion}" +} + +function validate_aks_version() { + if [[ "${USE_AKS_WELL_TESTED_VERSION,,}" == "true" ]]; then + local aksWellTestedVersionFile=aks_well_tested_version.json + # download the json file that has well-tested version from weblogic-azure repo. + curl -L "${gitUrl4AksWellTestedVersionJsonFile}" --retry ${retryMaxAttempt} -o ${aksWellTestedVersionFile} + local aksWellTestedVersion=$(cat ${aksWellTestedVersionFile} | jq ".value" | tr -d "\"") + echo "AKS well-tested version: ${aksWellTestedVersion}" + # check if the well-tested version is supported in the location + local ret=$(az aks get-versions --location ${location} \ + | jq ".orchestrators[] | select(.orchestratorVersion == \"${aksWellTestedVersion}\") | .orchestratorVersion" \ + | tr -d "\"") + if [[ "${aksWellTestedVersion}" != "" ]] && [[ "${ret}" == "${aksWellTestedVersion}" ]]; then + outputAksVersion=${aksWellTestedVersion} + else + # if the well-tested version is invalid, use default version. + get_aks_default_version + outputAksVersion=${constDefaultAKSVersion} + fi + else + # check if the input version is supported in the location + local ret=$(az aks get-versions --location ${location} \ + | jq ".orchestrators[] | select(.orchestratorVersion == \"${AKS_VERSION}\") | .orchestratorVersion" \ + | tr -d "\"") + if [[ "${ret}" == "${AKS_VERSION}" ]]; then + outputAksVersion=${AKS_VERSION} + else + echo_stderr "ERROR: invalid aks version ${AKS_VERSION} in ${location}." + exit 1 + fi + fi +} + +function validate_aks_networking() { + local networkPluginMode=$(az aks show -g ${AKS_CLUSTER_RESOURCEGROUP_NAME} -n ${AKS_CLUSTER_NAME} | jq '.networkProfile.networkPluginMode' | tr -d "\"") + local networkPlugin=$(az aks show -g ${AKS_CLUSTER_RESOURCEGROUP_NAME} -n ${AKS_CLUSTER_NAME} | jq '.networkProfile.networkPlugin' | tr -d "\"") + + if [[ "${networkPluginMode}" != "null" ]]; then + echo_stderr "ERROR: invalid network plugin mode ${networkPluginMode} for ${AKS_CLUSTER_NAME}." + exit 1 + fi + + if [[ "${networkPlugin}" != "azure" ]]; then + echo_stderr "ERROR: invalid network plugin ${networkPlugin} for ${AKS_CLUSTER_NAME}." + exit 1 + fi +} + +function enable_aks_managed_identity() { + local identityLength=$(az aks show -g ${AKS_CLUSTER_RESOURCEGROUP_NAME} -n ${AKS_CLUSTER_NAME} | jq '.identity | length') + echo "identityLength ${identityLength}" + + if [ $identityLength -lt 1 ]; then + echo "enable managed identity..." + # Your cluster is using service principal, and you are going to update the cluster to use systemassigned managed identity. + # After updating, your cluster's control plane and addon pods will switch to use managed identity, but kubelet will KEEP USING SERVICE PRINCIPAL until you upgrade your agentpool. + az aks update -y -g ${AKS_CLUSTER_RESOURCEGROUP_NAME} -n ${AKS_CLUSTER_NAME} --enable-managed-identity + + validate_status "Enable Applciation Gateway Ingress Controller for ${AKS_CLUSTER_NAME}." + fi +} + +# VNET input sample: +# { +# "name": "wlsaks-vnet", +# "resourceGroup": "haiche-test", +# "addressPrefixes": [ +# "10.3.0.0/28" +# ], +# "addressPrefix": "10.3.0.0/28", +# "newOrExisting": "new", +# "subnets": { +# "gatewaySubnet": { +# "name": "wls-aks-gateway-subnet", +# "addressPrefix": "10.3.0.0/29", +# "startAddress": "10.3.0.4" +# } +# } +# } +# To make sure the subnet only have application gateway +function validate_appgateway_vnet() { + echo_stdout "VNET for application gateway: ${VNET_FOR_APPLICATIONGATEWAY}" + local vnetName=$(echo ${VNET_FOR_APPLICATIONGATEWAY} | jq '.name' | tr -d "\"") + local vnetResourceGroup=$(echo ${VNET_FOR_APPLICATIONGATEWAY} | jq '.resourceGroup' | tr -d "\"") + local newOrExisting=$(echo ${VNET_FOR_APPLICATIONGATEWAY} | jq '.newOrExisting' | tr -d "\"") + local subnetName=$(echo ${VNET_FOR_APPLICATIONGATEWAY} | jq '.subnets.gatewaySubnet.name' | tr -d "\"") + + if [[ "${newOrExisting,,}" != "new" ]]; then + # the subnet can only have Application Gateway. + # query ipConfigurations: + # if lenght of ipConfigurations is greater than 0, the subnet fails to meet requirement of Application Gateway. + local ret=$(az network vnet show \ + -g ${vnetResourceGroup} \ + --name ${vnetName} \ + | jq ".subnets[] | select(.name==\"${subnetName}\") | .ipConfigurations | length") + + if [ $ret -gt 0 ]; then + echo_stderr "ERROR: invalid subnet for Application Gateway, the subnet has ${ret} connected device(s). Make sure the subnet is only for Application Gateway." + exit 1 + fi + fi +} + +function query_available_zones() { + if [[ "${createAKSCluster,,}" == "true" ]]; then + outputAvailableZones=$(az vm list-skus -l ${location} --size ${aksAgentPoolVMSize} --zone true | jq -c '.[] | .locationInfo[] | .zones') + fi + + if [ -z "${outputAvailableZones}" ]; then + outputAvailableZones="[]" + fi + + export outputAvailableZones="${outputAvailableZones}" +} + +function output_result() { + echo "AKS version: ${outputAksVersion}" + result=$(jq -n -c \ + --arg aksVersion "$outputAksVersion" \ + --arg agentAvailabilityZones "${outputAvailableZones}" \ + '{aksVersion: $aksVersion, agentAvailabilityZones: $agentAvailabilityZones}') + echo "result is: $result" + echo $result >$AZ_SCRIPTS_OUTPUT_PATH +} + +# main +location=$1 +createAKSCluster=$2 +aksAgentPoolVMSize=$3 +aksAgentPoolNodeCount=$4 +useOracleImage=$5 +wlsImageTag=$6 +userProvidedImagePath=$7 +enableCustomSSL=$8 +appGatewayCertificateOption=${9} +enableAppGWIngress=${10} +checkDNSZone=${11} + +outputAksVersion=${constDefaultAKSVersion} + +# install docker cli +install_docker + +validate_compute_resources + +validate_memory_resources + +validate_base_image_path + +validate_acr_admin_enabled + +validate_image_compatibility + +if [[ "${enableCustomSSL,,}" == "true" ]]; then + validate_wls_ssl_certificates +fi + +if [[ "${enableAppGWIngress,,}" == "true" ]]; then + validate_gateway_frontend_certificates +fi + +validate_dns_zone + +if [[ "${createAKSCluster,,}" == "true" ]]; then + validate_aks_version +fi + +# validate existing aks cluster +if [[ "${createAKSCluster,,}" != "true" ]]; then + validate_aks_networking + enable_aks_managed_identity +fi + +validate_appgateway_vnet + +query_available_zones + +output_result diff --git a/weblogic-azure-aks/src/main/arm/scripts/invokeSetupDBConnections.sh b/weblogic-azure-aks/src/main/arm/scripts/invokeSetupDBConnections.sh deleted file mode 100644 index 903e97ced..000000000 --- a/weblogic-azure-aks/src/main/arm/scripts/invokeSetupDBConnections.sh +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright (c) 2021, Oracle Corporation and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# This script runs on Azure Container Instance with Alpine Linux that Azure Deployment script creates. - -#Function to display usage message -function usage() { - usage=$(cat <<-END -Usage: -./invokeSetupDBConnections.sh - - - - - - - - - - - -END -) - echo_stdout "${usage}" - if [ $1 -eq 1 ]; then - echo_stderr "${usage}" - exit 1 - fi -} - -# Main script -export script="${BASH_SOURCE[0]}" -export scriptDir="$(cd "$(dirname "${script}")" && pwd)" - -source ${scriptDir}/utility.sh - -export aksClusterRGName=$1 -export aksClusterName=$2 -export databaseType=$3 -dbPassword=$4 -export dbUser=$5 -export dsConnectionURL=$6 -export jdbcDataSourceName=$7 -export wlsDomainUID=$8 -export wlsUser=$9 -wlsPassword=${10} -export dbOptType=${11} - -echo ${dbPassword} \ - ${wlsPassword} | \ - bash ./setupDBConnections.sh \ - ${aksClusterRGName} \ - ${aksClusterName} \ - ${databaseType} \ - ${dbUser} \ - ${dsConnectionURL} \ - ${jdbcDataSourceName} \ - ${wlsDomainUID} \ - ${wlsUser} \ - ${dbOptType} - -if [ $? -ne 0 ]; then - usage 1 -fi diff --git a/weblogic-azure-aks/src/main/arm/scripts/invokeSetupNetworking.sh b/weblogic-azure-aks/src/main/arm/scripts/invokeSetupNetworking.sh deleted file mode 100644 index 32edb91ad..000000000 --- a/weblogic-azure-aks/src/main/arm/scripts/invokeSetupNetworking.sh +++ /dev/null @@ -1,111 +0,0 @@ -# Copyright (c) 2021, Oracle Corporation and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# This script runs on Azure Container Instance with Alpine Linux that Azure Deployment script creates. - -#Function to display usage message -function usage() { - usage=$(cat <<-END -Usage: -./invokeSetupNetworking.sh - - - - - - - - - - - - - - - - - - - - - - - - - - - -END -) - echo_stdout "${usage}" - if [ $1 -eq 1 ]; then - echo_stderr "${usage}" - exit 1 - fi -} - -# Main script -export script="${BASH_SOURCE[0]}" -export scriptDir="$(cd "$(dirname "${script}")" && pwd)" - -source ${scriptDir}/utility.sh - -export aksClusterRGName=$1 -export aksClusterName=$2 -export wlsDomainName=$3 -export wlsDomainUID=$4 -export lbSvcValues=$5 -export enableAppGWIngress=$6 -export subID=$7 -export curRGName=${8} -export appgwName=${9} -export vnetName=${10} -spBase64String=${11} -export appgwForAdminServer=${12} -export enableCustomDNSAlias=${13} -export dnsRGName=${14} -export dnsZoneName=${15} -export dnsAdminLabel=${16} -export dnsClusterLabel=${17} -export appgwAlias=${18} -export enableInternalLB=${19} -export appgwFrontendSSLCertData=${20} -appgwFrontendSSLCertPsw=${21} -export appgwCertificateOption=${22} -export enableCustomSSL=${23} -export enableCookieBasedAffinity=${24} -export enableRemoteConsole=${25} -export dnszoneAdminT3ChannelLabel=${26} -export dnszoneClusterT3ChannelLabel=${27} - -echo ${spBase64String} \ - ${appgwFrontendSSLCertPsw} | \ - bash ./setupNetworking.sh \ - ${aksClusterRGName} \ - ${aksClusterName} \ - ${wlsDomainName} \ - ${wlsDomainUID} \ - ${lbSvcValues} \ - ${enableAppGWIngress} \ - ${subID} \ - ${curRGName} \ - ${appgwName} \ - ${vnetName} \ - ${appgwForAdminServer} \ - ${enableCustomDNSAlias} \ - ${dnsRGName} \ - ${dnsZoneName} \ - ${dnsAdminLabel} \ - ${dnsClusterLabel} \ - ${appgwAlias} \ - ${enableInternalLB} \ - ${appgwFrontendSSLCertData} \ - ${appgwCertificateOption} \ - ${enableCustomSSL} \ - ${enableCookieBasedAffinity} \ - ${enableRemoteConsole} \ - ${dnszoneAdminT3ChannelLabel} \ - ${dnszoneClusterT3ChannelLabel} - -if [ $? -ne 0 ]; then - usage 1 -fi diff --git a/weblogic-azure-aks/src/main/arm/scripts/invokeSetupWLSDomain.sh b/weblogic-azure-aks/src/main/arm/scripts/invokeSetupWLSDomain.sh deleted file mode 100644 index 22d559a25..000000000 --- a/weblogic-azure-aks/src/main/arm/scripts/invokeSetupWLSDomain.sh +++ /dev/null @@ -1,135 +0,0 @@ -# Copyright (c) 2021, Oracle Corporation and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# This script runs on Azure Container Instance with Alpine Linux that Azure Deployment script creates. - -#Function to display usage message -function usage() { - usage=$(cat <<-END -Usage: -./invokeSetupWLSDomain.sh - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -END -) - echo_stdout "${usage}" - if [ $1 -eq 1 ]; then - echo_stderr "${usage}" - exit 1 - fi -} - -# Main script -export script="${BASH_SOURCE[0]}" -export scriptDir="$(cd "$(dirname "${script}")" && pwd)" - -source ${scriptDir}/utility.sh - -export ocrSSOUser=$1 -ocrSSOPSW=$2 -export aksClusterRGName=$3 -export aksClusterName=$4 -export wlsImageTag=$5 -export acrName=$6 -export wlsDomainName=$7 -export wlsDomainUID=$8 -export wlsUserName=$9 -wlsPassword=${10} -wdtRuntimePassword=${11} -export wlsCPU=${12} -export wlsMemory=${13} -export managedServerPrefix=${14} -export appReplicas=${15} -export appPackageUrls=${16} -export currentResourceGroup=${17} -export scriptURL=${18} -export storageAccountName=${19} -export wlsClusterSize=${20} -export enableCustomSSL=${21} -export wlsIdentityData=${22} -wlsIdentityPsw=${23} -export wlsIdentityType=${24} -export wlsIdentityAlias=${25} -wlsIdentityKeyPsw=${26} -export wlsTrustData=${27} -wlsTrustPsw=${28} -export wlsTrustType=${29} -export enablePV=${30} -export enableAdminT3Tunneling=${31} -export enableClusterT3Tunneling=${32} -export t3AdminPort=${33} -export t3ClusterPort=${34} -export wlsJavaOption=${35} - -echo ${ocrSSOPSW} \ - ${wlsPassword} \ - ${wdtRuntimePassword} \ - ${wlsIdentityPsw} \ - ${wlsIdentityKeyPsw} \ - ${wlsTrustPsw} | \ - bash ./setupWLSDomain.sh \ - ${ocrSSOUser} \ - ${aksClusterRGName} \ - ${aksClusterName} \ - ${wlsImageTag} \ - ${acrName} \ - ${wlsDomainName} \ - ${wlsDomainUID} \ - ${wlsUserName} \ - ${wlsCPU} \ - ${wlsMemory} \ - ${managedServerPrefix} \ - ${appReplicas} \ - ${appPackageUrls} \ - ${currentResourceGroup} \ - ${scriptURL} \ - ${storageAccountName} \ - ${wlsClusterSize} \ - ${enableCustomSSL} \ - ${wlsIdentityData} \ - ${wlsIdentityType} \ - ${wlsIdentityAlias} \ - ${wlsTrustData} \ - ${wlsTrustType} \ - ${enablePV} \ - ${enableAdminT3Tunneling} \ - ${enableClusterT3Tunneling} \ - ${t3AdminPort} \ - ${t3ClusterPort} \ - ${wlsJavaOption} - -if [ $? -ne 0 ]; then - usage 1 -fi diff --git a/weblogic-azure-aks/src/main/arm/scripts/invokeUpdateApplications.sh b/weblogic-azure-aks/src/main/arm/scripts/invokeUpdateApplications.sh index 2d5234750..7d3b7ca0c 100644 --- a/weblogic-azure-aks/src/main/arm/scripts/invokeUpdateApplications.sh +++ b/weblogic-azure-aks/src/main/arm/scripts/invokeUpdateApplications.sh @@ -20,6 +20,8 @@ Usage: + + END ) echo_stdout "${usage}" @@ -48,6 +50,8 @@ export appPackageUrls=${10} export scriptURL=${11} export appStorageAccountName=${12} export appContainerName=${13} +export userProvidedImagePath=${14} +export useOracleImage=${15} echo ${ocrSSOPSW} | \ bash ./updateApplications.sh \ @@ -62,7 +66,9 @@ echo ${ocrSSOPSW} | \ ${appPackageUrls} \ ${scriptURL} \ ${appStorageAccountName} \ - ${appContainerName} + ${appContainerName} \ + ${userProvidedImagePath} \ + ${useOracleImage} if [ $? -ne 0 ]; then usage 1 diff --git a/weblogic-azure-aks/src/main/arm/scripts/pv.yaml.template b/weblogic-azure-aks/src/main/arm/scripts/pv.yaml.template index 349ced5c6..74ee054b1 100644 --- a/weblogic-azure-aks/src/main/arm/scripts/pv.yaml.template +++ b/weblogic-azure-aks/src/main/arm/scripts/pv.yaml.template @@ -21,7 +21,7 @@ spec: namespace: @NAMESPACE@ azureFile: secretName: azure-secret - shareName: weblogic + shareName: @FILE_SHARE_NAME@ readOnly: false mountOptions: - dir_mode=0777 diff --git a/weblogic-azure-aks/src/main/arm/scripts/queryStorageAccount.sh b/weblogic-azure-aks/src/main/arm/scripts/queryStorageAccount.sh deleted file mode 100644 index a9241912e..000000000 --- a/weblogic-azure-aks/src/main/arm/scripts/queryStorageAccount.sh +++ /dev/null @@ -1,44 +0,0 @@ -export aksClusterRGName=$1 -export aksClusterName=$2 - -export currentStorageAccount="null" - -# Connect to AKS cluster -function connect_aks_cluster() { - az aks get-credentials \ - --resource-group ${aksClusterRGName} \ - --name ${aksClusterName} \ - --overwrite-existing -} - -function query_storage_account() { - echo "install kubectl" - az aks install-cli - - echo "get pv name" - pvName=$(kubectl get pv -o json | - jq '.items[] | select(.status.phase=="Bound") | [.metadata.name] | .[0]' | - tr -d "\"") - - if [[ "${pvName}" != "null" ]] && [[ "${pvName}" != "" ]]; then - # this is a workaround for update domain using marketplace offer. - # the offer will create a new storage account in a new resource group if there is no storage attached. - currentStorageAccount=$(kubectl get pv ${pvName} -o json | jq '. | .metadata.labels.storageAccount' | tr -d "\"") - fi -} - -function output_result() { - echo ${currentStorageAccount} - - result=$(jq -n -c \ - --arg storageAccount $currentStorageAccount \ - '{storageAccount: $storageAccount}') - echo "result is: $result" - echo $result >$AZ_SCRIPTS_OUTPUT_PATH -} - -connect_aks_cluster - -query_storage_account - -output_result diff --git a/weblogic-azure-aks/src/main/arm/scripts/setupDBConnections.sh b/weblogic-azure-aks/src/main/arm/scripts/setupDBConnections.sh index fd5283aa8..446976b02 100644 --- a/weblogic-azure-aks/src/main/arm/scripts/setupDBConnections.sh +++ b/weblogic-azure-aks/src/main/arm/scripts/setupDBConnections.sh @@ -1,30 +1,31 @@ -# Copyright (c) 2021, Oracle Corporation and/or its affiliates. +# Copyright (c) 2021, 2024 Oracle Corporation and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. echo "Script ${0} starts" -# read from stdin -function read_sensitive_parameters_from_stdin() { - read dbPassword wlsPassword -} - #Function to display usage message function usage() { usage=$(cat <<-END Usage: -echo | - ./setupDBConnections.sh - - - - - - - - - +You must specify the following environment variables: +AKS_RESOURCE_GROUP_NAME: the name of resource group that runs the AKS cluster. +AKS_NAME: the name of the AKS cluster. +DATABASE_TYPE: one of the supported database types. +DB_CONFIGURATION_TYPE: createOrUpdate: create a new data source connection, or update an existing data source connection. delete: delete an existing data source connection. +DB_SHIBBOLETH: password for Database. +DB_USER: user id of Database. +DB_CONNECTION_STRING: JDBC Connection String. +DB_DRIVER_NAME: datasource driver name, must be specified if database type is otherdb. +ENABLE_SHIBBOLETHLESS_CONNECTION: true to enable passwordless connection +GLOBAL_TRANSATION_PROTOCOL: Determines the transaction protocol (global transaction processing behavior) for the data source. +JDBC_DATASOURCE_NAME: JNDI Name for JDBC Datasource. +TEST_TABLE_NAME: the name of the database table to use when testing physical database connections. This name is required when you specify a Test Frequency and enable Test Reserved Connections. +WLS_DOMAIN_UID: UID of WebLogic domain, used in WebLogic Operator. +WLS_DOMAIN_USER: user name for WebLogic Administrator. +WLS_DOMAIN_SHIBBOLETH: passowrd for WebLogic Administrator. END ) + echo_stdout "${usage}" if [ $1 -eq 1 ]; then echo_stderr "${usage}" @@ -34,53 +35,54 @@ END #Function to validate input function validate_input() { - if [[ -z "$aksClusterRGName" || -z "${aksClusterName}" ]]; then - echo_stderr "aksClusterRGName and aksClusterName are required. " + if [[ -z "$AKS_RESOURCE_GROUP_NAME" || -z "${AKS_NAME}" ]]; then + echo_stderr "AKS_RESOURCE_GROUP_NAME and AKS_NAME are required. " usage 1 fi - if [ -z "$databaseType" ]; then - echo_stderr "databaseType is required. " + if [ -z "$DATABASE_TYPE" ]; then + echo_stderr "DATABASE_TYPE is required. " usage 1 fi - if [[ -z "$dbPassword" || -z "${dbUser}" ]]; then - echo_stderr "dbPassword and dbUser are required. " + if [[ -z "${DB_SHIBBOLETH}" || -z "${DB_USER}" ]]; then + echo_stderr "DB_SHIBBOLETH and DB_USER are required. " usage 1 fi - if [ -z "$dsConnectionURL" ]; then - echo_stderr "dsConnectionURL is required. " + if [ -z "$DB_CONNECTION_STRING" ]; then + echo_stderr "DB_CONNECTION_STRING is required. " usage 1 fi - if [ -z "$jdbcDataSourceName" ]; then - echo_stderr "jdbcDataSourceName is required. " + if [ -z "$JDBC_DATASOURCE_NAME" ]; then + echo_stderr "JDBC_DATASOURCE_NAME is required. " usage 1 fi - if [ -z "$wlsDomainUID" ]; then - echo_stderr "wlsDomainUID is required. " + if [ -z "$WLS_DOMAIN_UID" ]; then + echo_stderr "WLS_DOMAIN_UID is required. " usage 1 fi - if [[ -z "$wlsUser" || -z "${wlsPassword}" ]]; then - echo_stderr "wlsUser and wlsPassword are required. " + if [[ -z "$WLS_DOMAIN_USER" || -z "${WLS_DOMAIN_SHIBBOLETH}" ]]; then + echo_stderr "WLS_DOMAIN_USER and WLS_DOMAIN_SHIBBOLETH are required. " usage 1 fi -} -# Connect to AKS cluster -function connect_aks_cluster() { - az aks get-credentials \ - --resource-group ${aksClusterRGName} \ - --name ${aksClusterName} \ - --overwrite-existing + # reset shibboleth + if [[ "${ENABLE_SHIBBOLETHLESS_CONNECTION,,}" == "true" ]]; then + DB_SHIBBOLETH="" + + if [[ "${DATABASE_TYPE}" == "${constDBTypeSqlServer}" ]]; then + DB_USER="" + fi + fi } function create_datasource_model_configmap_and_secret() { echo "get data source secret name" - jndiLabel=${jdbcDataSourceName//\//\_} + jndiLabel=${JDBC_DATASOURCE_NAME//\//\_} secretLen=$(kubectl get secret -n ${wlsDomainNS} -l datasource.JNDI="${jndiLabel}" -o json \ | jq '.items | length') if [ ${secretLen} -ge 1 ];then @@ -88,27 +90,19 @@ function create_datasource_model_configmap_and_secret() { | jq ".items[0].metadata.name" \ | tr -d "\"") else - dbSecretName="ds-secret-${databaseType}-${datetime}" + dbSecretName="ds-secret-${DATABASE_TYPE}-${datetime}" fi echo "Data source secret name: ${dbSecretName}" chmod ugo+x $scriptDir/dbUtility.sh - echo "${dbPassword}" | \ - bash $scriptDir/dbUtility.sh \ - ${databaseType} \ - "${dbUser}" \ - "${dsConnectionURL}" \ - "${jdbcDataSourceName}" \ - "${wlsDomainUID}" \ - "${dbSecretName}" \ - "${optTypeUpdate}" + bash $scriptDir/dbUtility.sh ${dbSecretName} ${optTypeUpdate} } function apply_datasource_to_domain() { echo "apply datasoure" # get domain configurations domainConfigurationJsonFile=$scriptDir/domain.json - kubectl -n ${wlsDomainNS} get domain ${wlsDomainUID} -o json >${domainConfigurationJsonFile} + kubectl -n ${wlsDomainNS} get domain ${WLS_DOMAIN_UID} -o json >${domainConfigurationJsonFile} restartVersion=$(cat ${domainConfigurationJsonFile} | jq '. | .spec.restartVersion' | tr -d "\"") secretList=$(cat ${domainConfigurationJsonFile} | jq -r '. | .spec.configuration.secrets') @@ -136,16 +130,18 @@ function apply_datasource_to_domain() { # apply the secret # restart the domain timestampBeforePatchingDomain=$(date +%s) - kubectl -n ${wlsDomainNS} patch domain ${wlsDomainUID} \ + kubectl -n ${wlsDomainNS} patch domain ${WLS_DOMAIN_UID} \ --type=json \ -p '[{"op": "replace", "path": "/spec/restartVersion", "value": "'${restartVersion}'" }, {"op": "replace", "path": "/spec/configuration/model/configMap", "value":'${wlsConfigmapName}'}, {"op": "replace", "path": "/spec/configuration/secrets", "value": '${secretStrings}'}]' + + utility_validate_status "Patch DB configuration." } function remove_datasource_from_domain() { echo "remove datasoure secret from domain configuration" # get domain configurations domainConfigurationJsonFile=$scriptDir/domain.json - kubectl -n ${wlsDomainNS} get domain ${wlsDomainUID} -o json >${domainConfigurationJsonFile} + kubectl -n ${wlsDomainNS} get domain ${WLS_DOMAIN_UID} -o json >${domainConfigurationJsonFile} restartVersion=$(cat ${domainConfigurationJsonFile} | jq '. | .spec.restartVersion' | tr -d "\"") secretList=$(cat ${domainConfigurationJsonFile} | jq -r '. | .spec.configuration.secrets') @@ -183,20 +179,25 @@ function remove_datasource_from_domain() { # apply the secret # restart the domain timestampBeforePatchingDomain=$(date +%s) - kubectl -n ${wlsDomainNS} patch domain ${wlsDomainUID} \ + kubectl -n ${wlsDomainNS} patch domain ${WLS_DOMAIN_UID} \ --type=json \ -p '[{"op": "replace", "path": "/spec/restartVersion", "value": "'${restartVersion}'" }, {"op": "replace", "path": "/spec/configuration/model/configMap", "value":'${wlsConfigmapName}'}, {"op": "replace", "path": "/spec/configuration/secrets", "value": '${secretStrings}'}]' + + utility_validate_status "Patch DB configuration." } function wait_for_operation_completed() { # Make sure all of the pods are running. - replicas=$(kubectl -n ${wlsDomainNS} get domain ${wlsDomainUID} -o json \ - | jq '. | .spec.clusters[] | .replicas') + + clusterName=$(kubectl get cluster -n ${wlsDomainNS} -o json | jq -r '.items[0].metadata.name') + + replicas=$(kubectl -n ${wlsDomainNS} get cluster ${clusterName} -o json \ + | jq '. | .spec.replicas') utility_wait_for_pod_restarted \ ${timestampBeforePatchingDomain} \ ${replicas} \ - ${wlsDomainUID} \ + ${WLS_DOMAIN_UID} \ ${checkPodStatusMaxAttemps} \ ${checkPodStatusInterval} @@ -208,19 +209,11 @@ function wait_for_operation_completed() { } function delete_datasource() { - echo "remove secret and model of data source ${jdbcDataSourceName}" + echo "remove secret and model of data source ${JDBC_DATASOURCE_NAME}" # remove secret # remove model chmod ugo+x $scriptDir/dbUtility.sh - echo "${dbPassword}" | \ - bash $scriptDir/dbUtility.sh \ - ${databaseType} \ - "${dbUser}" \ - "${dsConnectionURL}" \ - "${jdbcDataSourceName}" \ - "${wlsDomainUID}" \ - "${dbSecretName}" \ - "${optTypeDelete}" + bash $scriptDir/dbUtility.sh ${dbSecretName} ${optTypeDelete} # update weblogic domain remove_datasource_from_domain @@ -233,7 +226,7 @@ function validate_datasource() { testDatasourceScript=${scriptDir}/${dsScriptFileName} podNum=$(kubectl -n ${wlsDomainNS} get pod -l weblogic.clusterName=${wlsClusterName} -o json | jq '.items| length') if [ ${podNum} -le 0 ]; then - echo "Ensure your cluster has at least one pod." + echo_stderr "Ensure your cluster has at least one pod." exit 1 fi @@ -245,11 +238,11 @@ function validate_datasource() { clusterTargetPort=$(kubectl get svc ${wlsClusterSvcName} -n ${wlsDomainNS} -o json | jq '.spec.ports[] | select(.name=="default") | .port') t3ConnectionString="t3://${wlsClusterSvcName}.${wlsDomainNS}.svc.cluster.local:${clusterTargetPort}" cat <${testDatasourceScript} -connect('${wlsUser}', '${wlsPassword}', '${t3ConnectionString}') +connect('${WLS_DOMAIN_USER}', '${WLS_DOMAIN_SHIBBOLETH}', '${t3ConnectionString}') serverRuntime() print 'start to query data source jndi bean' dsMBeans = cmo.getJDBCServiceRuntime().getJDBCDataSourceRuntimeMBeans() -ds_name = '${jdbcDataSourceName}' +ds_name = '${JDBC_DATASOURCE_NAME}' for ds in dsMBeans: if (ds_name == ds.getName()): print 'DS name is: '+ds.getName() @@ -259,54 +252,46 @@ EOF echo "copy test script ${testDatasourceScript} to pod path /tmp/${dsScriptFileName}" targetDSFilePath=/tmp/${dsScriptFileName} kubectl cp ${testDatasourceScript} -n ${wlsDomainNS} ${podName}:${targetDSFilePath} - kubectl exec -it ${podName} -n ${wlsDomainNS} -c ${wlsContainerName} -- bash -c "wlst.sh ${targetDSFilePath}" | grep "State is Running" + echo "execute script to validate data source ${JDBC_DATASOURCE_NAME} in pod ${podName} with wlsContainerName ${wlsContainerName}" + kubectl exec ${podName} -n ${wlsDomainNS} -c ${wlsContainerName} -- bash -c "wlst.sh ${targetDSFilePath}" | grep "State is Running" if [ $? == 1 ];then - echo "Failed to configure datasource ${jdbcDataSourceName}. Please make sure the input values are correct." - delete_datasource + echo_stderr "Failed to configure datasource ${JDBC_DATASOURCE_NAME}. Please make sure the input values are correct." exit 1 + else + echo "Data source ${JDBC_DATASOURCE_NAME} is configured successfully." fi } # Main script +set -Eo pipefail + export script="${BASH_SOURCE[0]}" export scriptDir="$(cd "$(dirname "${script}")" && pwd)" source ${scriptDir}/common.sh source ${scriptDir}/utility.sh -export aksClusterRGName=$1 -export aksClusterName=$2 -export databaseType=$3 -export dbUser=$4 -export dsConnectionURL=$5 -export jdbcDataSourceName=$6 -export wlsDomainUID=$7 -export wlsUser=$8 -export dbOptType=$9 - export datetime=$(date +%s) export optTypeDelete='delete' export optTypeUpdate='createOrUpdate' export wlsClusterName="cluster-1" -export wlsClusterSvcName="${wlsDomainUID}-cluster-${wlsClusterName}" -export wlsConfigmapName="${wlsDomainUID}-wdt-config-map" -export wlsDomainNS="${wlsDomainUID}-ns" - -read_sensitive_parameters_from_stdin +export wlsClusterSvcName="${WLS_DOMAIN_UID}-cluster-${wlsClusterName}" +export wlsConfigmapName="${WLS_DOMAIN_UID}-wdt-config-map" +export wlsDomainNS="${WLS_DOMAIN_UID}-ns" validate_input -connect_aks_cluster +connect_aks $AKS_NAME $AKS_RESOURCE_GROUP_NAME install_kubectl -if [[ "${dbOptType}" == "${optTypeDelete}" ]];then - echo "delete date source: ${jdbcDataSourceName}" +if [[ "${DB_CONFIGURATION_TYPE}" == "${optTypeDelete}" ]];then + echo "delete date source: ${JDBC_DATASOURCE_NAME}" delete_datasource else - echo "create/update data source: ${jdbcDataSourceName}" + echo "create/update data source: ${JDBC_DATASOURCE_NAME}" create_datasource_model_configmap_and_secret apply_datasource_to_domain wait_for_operation_completed diff --git a/weblogic-azure-aks/src/main/arm/scripts/setupNetworking.sh b/weblogic-azure-aks/src/main/arm/scripts/setupNetworking.sh index 0fb9500e7..084524d72 100644 --- a/weblogic-azure-aks/src/main/arm/scripts/setupNetworking.sh +++ b/weblogic-azure-aks/src/main/arm/scripts/setupNetworking.sh @@ -1,13 +1,8 @@ -# Copyright (c) 2021, Oracle Corporation and/or its affiliates. +# Copyright (c) 2021, 2024 Oracle Corporation and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. echo "Script ${0} starts" -# read from stdin -function read_sensitive_parameters_from_stdin() { - read spBase64String appgwFrontendSSLCertPsw -} - # Install latest kubectl and Helm function install_utilities() { if [ -d "apps" ]; then @@ -21,251 +16,133 @@ function install_utilities() { install_kubectl } -#Function to display usage message -function usage() { - usage=$( - cat <<-END -Usage: -echo | - ./setupNetworking.sh - - - - - - - - - - - - - - - - - - - - - - - - - -END - ) - echo_stdout ${usage} - if [ $1 -eq 1 ]; then - echo_stderr ${usage} - exit 1 - fi -} - #Function to validate input function validate_input() { - if [[ -z "$aksClusterRGName" || -z "${aksClusterName}" ]]; then + if [[ -z "$AKS_CLUSTER_RG_NAME" || -z "${AKS_CLUSTER_NAME}" ]]; then echo_stderr "AKS cluster name and resource group name are required. " - usage 1 + exit 1 fi - if [[ -z "$wlsDomainName" || -z "${wlsDomainUID}" ]]; then + if [[ -z "$WLS_DOMAIN_NAME" || -z "${WLS_DOMAIN_UID}" ]]; then echo_stderr "WebLogic domain name and WebLogic domain UID are required. " - usage 1 - fi - - if [ -z "$lbSvcValues" ]; then - echo_stderr "lbSvcValues is required. " - usage 1 - fi - - if [ -z "$enableAppGWIngress" ]; then - echo_stderr "enableAppGWIngress is required. " - usage 1 - fi - - if [ -z "$subID" ]; then - echo_stderr "subID is required. " - usage 1 + exit 1 fi - if [ -z "$curRGName" ]; then - echo_stderr "curRGName is required. " - usage 1 + if [ -z "$LB_SVC_VALUES" ]; then + echo_stderr "LB_SVC_VALUES is required. " + exit 1 fi - if [ -z "$appgwName" ]; then - echo_stderr "appgwName is required. " - usage 1 + if [ -z "$ENABLE_AGIC" ]; then + echo_stderr "ENABLE_AGIC is required. " + exit 1 fi - if [ -z "$vnetName" ]; then - echo_stderr "vnetName is required. " - usage 1 + if [ -z "$CURRENT_RG_NAME" ]; then + echo_stderr "CURRENT_RG_NAME is required. " + exit 1 fi - if [ -z "$spBase64String" ]; then - echo_stderr "spBase64String is required. " - usage 1 + if [ -z "$APPGW_NAME" ]; then + echo_stderr "APPGW_NAME is required. " + exit 1 fi - if [ -z "$appgwForAdminServer" ]; then - echo_stderr "appgwForAdminServer is required. " - usage 1 + if [ -z "$APPGW_USE_PRIVATE_IP" ]; then + echo_stderr "APPGW_USE_PRIVATE_IP is required. " + exit 1 fi - if [ -z "$enableCustomDNSAlias" ]; then - echo_stderr "enableCustomDNSAlias is required. " - usage 1 + if [ -z "$APPGW_FOR_ADMIN_SERVER" ]; then + echo_stderr "APPGW_FOR_ADMIN_SERVER is required. " + exit 1 fi - if [[ -z "$dnsRGName" || -z "${dnsZoneName}" ]]; then - echo_stderr "dnsZoneName and dnsRGName are required. " - usage 1 + if [ -z "$ENABLE_DNS_CONFIGURATION" ]; then + echo_stderr "ENABLE_DNS_CONFIGURATION is required. " + exit 1 fi - if [ -z "$dnsAdminLabel" ]; then - echo_stderr "dnsAdminLabel is required. " - usage 1 + if [[ -z "$DNS_ZONE_RG_NAME" || -z "${DNS_ZONE_NAME}" ]]; then + echo_stderr "DNS_ZONE_NAME and DNS_ZONE_RG_NAME are required. " + exit 1 fi - if [ -z "$dnsClusterLabel" ]; then - echo_stderr "dnsClusterLabel is required. " - usage 1 + if [ -z "$DNS_ADMIN_LABEL" ]; then + echo_stderr "DNS_ADMIN_LABEL is required. " + exit 1 fi - if [ -z "$appgwAlias" ]; then - echo_stderr "appgwAlias is required. " - usage 1 + if [ -z "$DNS_CLUSTER_LABEL" ]; then + echo_stderr "DNS_CLUSTER_LABEL is required. " + exit 1 fi - if [ -z "$enableInternalLB" ]; then - echo_stderr "enableInternalLB is required. " - usage 1 + if [ -z "$APPGW_ALIAS" ]; then + echo_stderr "APPGW_ALIAS is required. " + exit 1 fi - if [[ -z "$appgwFrontendSSLCertData" || -z "${appgwFrontendSSLCertPsw}" ]]; then - echo_stderr "appgwFrontendSSLCertData and appgwFrontendSSLCertPsw are required. " - usage 1 + if [ -z "$USE_INTERNAL_LB" ]; then + echo_stderr "USE_INTERNAL_LB is required. " + exit 1 fi - if [ -z "$enableCustomSSL" ]; then - echo_stderr "enableCustomSSL is required. " - usage 1 + if [ -z "$ENABLE_CUSTOM_SSL" ]; then + echo_stderr "ENABLE_CUSTOM_SSL is required. " + exit 1 fi - if [ -z "$enableCookieBasedAffinity" ]; then - echo_stderr "enableCookieBasedAffinity is required. " - usage 1 + if [ -z "$ENABLE_COOKIE_BASED_AFFINITY" ]; then + echo_stderr "ENABLE_COOKIE_BASED_AFFINITY is required. " + exit 1 fi - if [ -z "$enableRemoteConsole" ]; then - echo_stderr "enableRemoteConsole is required. " - usage 1 + if [ -z "$APPGW_FOR_REMOTE_CONSOLE" ]; then + echo_stderr "APPGW_FOR_REMOTE_CONSOLE is required. " + exit 1 fi - if [ -z "$dnszoneAdminT3ChannelLabel" ]; then - echo_stderr "dnszoneAdminT3ChannelLabel is required. " - usage 1 + if [ -z "$DNS_ADMIN_T3_LABEL" ]; then + echo_stderr "DNS_ADMIN_T3_LABEL is required. " + exit 1 fi - if [ -z "$dnszoneClusterT3ChannelLabel" ]; then - echo_stderr "dnszoneClusterT3ChannelLabel is required. " - usage 1 + if [ -z "$DNS_CLUSTER_T3_LABEL" ]; then + echo_stderr "DNS_CLUSTER_T3_LABEL is required. " + exit 1 fi } -# Connect to AKS cluster -function connect_aks_cluster() { - az aks get-credentials --resource-group ${aksClusterRGName} --name ${aksClusterName} --overwrite-existing -} - function create_svc_lb() { # No lb svc inputs - if [[ "${lbSvcValues}" != "[]" ]]; then + if [[ "${LB_SVC_VALUES}" != "[]" ]]; then chmod ugo+x $scriptDir/createLbSvc.sh - bash $scriptDir/createLbSvc.sh \ - ${enableInternalLB} \ - ${enableCustomSSL} \ - ${enableCustomDNSAlias} \ - ${dnsRGName} \ - ${dnsZoneName} \ - ${dnsAdminLabel} \ - ${dnszoneAdminT3ChannelLabel} \ - ${dnsClusterLabel} \ - ${dnszoneClusterT3ChannelLabel} \ - "${lbSvcValues}" \ - ${wlsDomainUID} + bash $scriptDir/createLbSvc.sh fi } function create_appgw_ingress() { - if [[ "${enableAppGWIngress,,}" == "true" ]]; then + if [[ "${ENABLE_AGIC,,}" == "true" ]]; then chmod ugo+x $scriptDir/createAppGatewayIngress.sh - echo "$spBase64String" "$appgwFrontendSSLCertPsw" | - bash $scriptDir/createAppGatewayIngress.sh \ - ${aksClusterRGName} \ - ${aksClusterName} \ - ${wlsDomainUID} \ - ${subID} \ - ${curRGName} \ - ${appgwName} \ - ${vnetName} \ - ${appgwForAdminServer} \ - ${enableCustomDNSAlias} \ - ${dnsRGName} \ - ${dnsZoneName} \ - ${dnsAdminLabel} \ - ${dnsClusterLabel} \ - ${appgwAlias} \ - ${appgwFrontendSSLCertData} \ - ${appgwCertificateOption} \ - ${enableCustomSSL} \ - ${enableCookieBasedAffinity} \ - ${enableRemoteConsole} + bash $scriptDir/createAppGatewayIngress.sh fi } # Main script +set -Eeuo pipefail + export script="${BASH_SOURCE[0]}" export scriptDir="$(cd "$(dirname "${script}")" && pwd)" source ${scriptDir}/common.sh source ${scriptDir}/utility.sh -export aksClusterRGName=$1 -export aksClusterName=$2 -export wlsDomainName=$3 -export wlsDomainUID=$4 -export lbSvcValues=$5 -export enableAppGWIngress=$6 -export subID=$7 -export curRGName=${8} -export appgwName=${9} -export vnetName=${10} -export appgwForAdminServer=${11} -export enableCustomDNSAlias=${12} -export dnsRGName=${13} -export dnsZoneName=${14} -export dnsAdminLabel=${15} -export dnsClusterLabel=${16} -export appgwAlias=${17} -export enableInternalLB=${18} -export appgwFrontendSSLCertData=${19} -export appgwCertificateOption=${20} -export enableCustomSSL=${21} -export enableCookieBasedAffinity=${22} -export enableRemoteConsole=${23} -export dnszoneAdminT3ChannelLabel=${24} -export dnszoneClusterT3ChannelLabel=${25} - -read_sensitive_parameters_from_stdin - validate_input install_utilities -connect_aks_cluster +connect_aks $AKS_CLUSTER_NAME $AKS_CLUSTER_RG_NAME create_svc_lb diff --git a/weblogic-azure-aks/src/main/arm/scripts/setupWLSDomain.sh b/weblogic-azure-aks/src/main/arm/scripts/setupWLSDomain.sh index b95814e1f..6022152b8 100644 --- a/weblogic-azure-aks/src/main/arm/scripts/setupWLSDomain.sh +++ b/weblogic-azure-aks/src/main/arm/scripts/setupWLSDomain.sh @@ -1,49 +1,56 @@ -# Copyright (c) 2021, Oracle Corporation and/or its affiliates. +# Copyright (c) 2021, 2024, Oracle Corporation and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. # This script runs on Azure Container Instance with Alpine Linux that Azure Deployment script creates. +# env inputs: +# URL_3RD_DATASOURCE +# ORACLE_ACCOUNT_ENTITLED echo "Script ${0} starts" -# read from stdin -function read_sensitive_parameters_from_stdin() { - read ocrSSOPSW wlsPassword wdtRuntimePassword wlsIdentityPsw wlsIdentityKeyPsw wlsTrustPsw -} - #Function to display usage message function usage() { usage=$( cat <<-END -Usage: -echo | -./setupWLSDomain.sh - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Specify the following ENV variables: +ACR_NAME +AKS_CLUSTER_NAME +AKS_CLUSTER_RESOURCEGROUP_NAME +CURRENT_RESOURCEGROUP_NAME +ENABLE_ADMIN_CUSTOM_T3 +ENABLE_CLUSTER_CUSTOM_T3 +ENABLE_CUSTOM_SSL +ENABLE_PV +ORACLE_ACCOUNT_NAME +ORACLE_ACCOUNT_SHIBBOLETH +ORACLE_ACCOUNT_ENTITLED +SCRIPT_LOCATION +STORAGE_ACCOUNT_NAME +URL_3RD_DATASOURCE +USE_ORACLE_IMAGE +USER_PROVIDED_IMAGE_PATH +WLS_DOMAIN_NAME +WLS_DOMAIN_UID +WLS_ADMIN_SHIBBOLETH +WLS_ADMIN_USER_NAME +WLS_APP_PACKAGE_URLS +WLS_APP_REPLICAS +WLS_CLUSTER_SIZE +WLS_IMAGE_TAG +WLS_JAVA_OPTIONS +WLS_MANAGED_SERVER_PREFIX +WLS_RESOURCE_REQUEST_CPU +WLS_RESOURCE_REQUEST_MEMORY +WLS_SSL_IDENTITY_DATA +WLS_SSL_IDENTITY_SHIBBOLETH +WLS_SSL_IDENTITY_TYPE +WLS_SSL_TRUST_DATA +WLS_SSL_TRUST_SHIBBOLETH +WLS_SSL_TRUST_TYPE +WLS_SSL_PRIVATE_KEY_ALIAS +WLS_SSL_PRIVATE_KEY_SHIBBOLETH +WLS_T3_ADMIN_PORT +WLS_T3_CLUSTER_PORT +WLS_WDT_RUNTIME_PSW END ) echo_stdout ${usage} @@ -55,158 +62,168 @@ END #Function to validate input function validate_input() { - if [[ -z "$ocrSSOUser" || -z "${ocrSSOPSW}" ]]; then + if [ -z "$USE_ORACLE_IMAGE" ]; then + echo_stderr "USER_PROVIDED_IMAGE_PATH is required. " + usage 1 + fi + + if [[ "${USE_ORACLE_IMAGE,,}" == "${constTrue}" ]] && [[ -z "$ORACLE_ACCOUNT_NAME" || -z "${ORACLE_ACCOUNT_SHIBBOLETH}" ]]; then echo_stderr "Oracle SSO account is required. " usage 1 fi - if [[ -z "$aksClusterRGName" || -z "${aksClusterName}" ]]; then + if [[ -z "$AKS_CLUSTER_RESOURCEGROUP_NAME" || -z "${AKS_CLUSTER_NAME}" ]]; then echo_stderr "AKS cluster name and resource group name are required. " usage 1 fi - if [ -z "$wlsImageTag" ]; then - echo_stderr "wlsImageTag is required. " + if [ -z "$WLS_IMAGE_TAG" ]; then + echo_stderr "WLS_IMAGE_TAG is required. " usage 1 fi - if [ -z "$acrName" ]; then - echo_stderr "acrName is required. " + if [ -z "$ACR_NAME" ]; then + echo_stderr "ACR_NAME is required. " usage 1 fi - if [ -z "$wlsDomainName" ]; then - echo_stderr "wlsDomainName is required. " + if [ -z "$WLS_DOMAIN_NAME" ]; then + echo_stderr "WLS_DOMAIN_NAME is required. " usage 1 fi - if [ -z "$wlsDomainUID" ]; then - echo_stderr "wlsDomainUID is required. " + if [ -z "$WLS_DOMAIN_UID" ]; then + echo_stderr "WLS_DOMAIN_UID is required. " usage 1 fi - if [ -z "$wlsUserName" ]; then - echo_stderr "wlsUserName is required. " + if [ -z "$WLS_ADMIN_USER_NAME" ]; then + echo_stderr "WLS_ADMIN_USER_NAME is required. " usage 1 fi - if [ -z "$wlsPassword" ]; then - echo_stderr "wlsPassword is required. " + if [ -z "$WLS_ADMIN_SHIBBOLETH" ]; then + echo_stderr "WLS_ADMIN_SHIBBOLETH is required. " usage 1 fi - if [ -z "$wdtRuntimePassword" ]; then - echo_stderr "wdtRuntimePassword is required. " + if [ -z "$WLS_WDT_RUNTIME_PSW" ]; then + echo_stderr "WLS_WDT_RUNTIME_PSW is required. " usage 1 fi - if [ -z "$wlsCPU" ]; then - echo_stderr "wlsCPU is required. " + if [ -z "$WLS_RESOURCE_REQUEST_CPU" ]; then + echo_stderr "WLS_RESOURCE_REQUEST_CPU is required. " usage 1 fi - if [ -z "$wlsMemory" ]; then - echo_stderr "wlsMemory is required. " + if [ -z "$WLS_RESOURCE_REQUEST_MEMORY" ]; then + echo_stderr "WLS_RESOURCE_REQUEST_MEMORY is required. " usage 1 fi - if [ -z "$managedServerPrefix" ]; then - echo_stderr "managedServerPrefix is required. " + if [ -z "$WLS_MANAGED_SERVER_PREFIX" ]; then + echo_stderr "WLS_MANAGED_SERVER_PREFIX is required. " usage 1 fi - if [ -z "$appReplicas" ]; then - echo_stderr "appReplicas is required. " + if [ -z "$WLS_APP_REPLICAS" ]; then + echo_stderr "WLS_APP_REPLICAS is required. " usage 1 fi - if [ -z "$appPackageUrls" ]; then - echo_stderr "appPackageUrls is required. " + if [ -z "$WLS_APP_PACKAGE_URLS" ]; then + echo_stderr "WLS_APP_PACKAGE_URLS is required. " usage 1 fi - if [ -z "$currentResourceGroup" ]; then - echo_stderr "currentResourceGroup is required. " + if [ -z "$CURRENT_RESOURCEGROUP_NAME" ]; then + echo_stderr "CURRENT_RESOURCEGROUP_NAME is required. " usage 1 fi - if [ -z "$scriptURL" ]; then - echo_stderr "scriptURL is required. " + if [ -z "$SCRIPT_LOCATION" ]; then + echo_stderr "SCRIPT_LOCATION is required. " usage 1 fi - if [ -z "$storageAccountName" ]; then - echo_stderr "storageAccountName is required. " + if [ -z "$STORAGE_ACCOUNT_NAME" ]; then + echo_stderr "STORAGE_ACCOUNT_NAME is required. " usage 1 fi - if [ -z "$wlsClusterSize" ]; then - echo_stderr "wlsClusterSize is required. " + if [ -z "$WLS_CLUSTER_SIZE" ]; then + echo_stderr "WLS_CLUSTER_SIZE is required. " usage 1 fi - if [ -z "$enableCustomSSL" ]; then - echo_stderr "enableCustomSSL is required. " + if [ -z "$ENABLE_CUSTOM_SSL" ]; then + echo_stderr "ENABLE_CUSTOM_SSL is required. " usage 1 fi - if [[ -z "$wlsIdentityData" || -z "${wlsIdentityPsw}" ]]; then - echo_stderr "wlsIdentityPsw and wlsIdentityData are required. " + if [[ -z "$WLS_SSL_IDENTITY_DATA" || -z "${WLS_SSL_IDENTITY_SHIBBOLETH}" ]]; then + echo_stderr "WLS_SSL_IDENTITY_SHIBBOLETH and WLS_SSL_IDENTITY_DATA are required. " usage 1 fi - if [ -z "$wlsIdentityType" ]; then - echo_stderr "wlsIdentityType is required. " + if [ -z "$WLS_SSL_IDENTITY_TYPE" ]; then + echo_stderr "WLS_SSL_IDENTITY_TYPE is required. " usage 1 fi - if [[ -z "$wlsIdentityAlias" || -z "${wlsIdentityKeyPsw}" ]]; then - echo_stderr "wlsIdentityAlias and wlsIdentityKeyPsw are required. " + if [[ -z "$WLS_SSL_PRIVATE_KEY_ALIAS" || -z "${WLS_SSL_PRIVATE_KEY_SHIBBOLETH}" ]]; then + echo_stderr "WLS_SSL_PRIVATE_KEY_ALIAS and WLS_SSL_PRIVATE_KEY_SHIBBOLETH are required. " usage 1 fi - if [[ -z "$wlsTrustData" || -z "${wlsTrustPsw}" ]]; then - echo_stderr "wlsIdentityAlias and wlsIdentityKeyPsw are required. " + if [[ -z "$WLS_SSL_TRUST_DATA" || -z "${WLS_SSL_TRUST_SHIBBOLETH}" ]]; then + echo_stderr "WLS_SSL_TRUST_DATA and WLS_SSL_TRUST_SHIBBOLETH are required. " usage 1 fi - if [ -z "$wlsTrustType" ]; then - echo_stderr "wlsTrustType is required. " + if [ -z "$WLS_SSL_TRUST_TYPE" ]; then + echo_stderr "WLS_SSL_TRUST_TYPE is required. " usage 1 fi - if [ -z "$enablePV" ]; then - echo_stderr "enablePV is required. " + if [ -z "$ENABLE_PV" ]; then + echo_stderr "ENABLE_PV is required. " usage 1 fi - if [ -z "$enableAdminT3Tunneling" ]; then - echo_stderr "enableAdminT3Tunneling is required. " + if [ -z "$ENABLE_ADMIN_CUSTOM_T3" ]; then + echo_stderr "ENABLE_ADMIN_CUSTOM_T3 is required. " usage 1 fi - if [ -z "$enableClusterT3Tunneling" ]; then - echo_stderr "enableClusterT3Tunneling is required. " + if [ -z "$ENABLE_CLUSTER_CUSTOM_T3" ]; then + echo_stderr "ENABLE_CLUSTER_CUSTOM_T3 is required. " usage 1 fi - if [ -z "$t3AdminPort" ]; then - echo_stderr "t3AdminPort is required. " + if [ -z "$WLS_T3_ADMIN_PORT" ]; then + echo_stderr "WLS_T3_ADMIN_PORT is required. " usage 1 fi - if [ -z "$t3ClusterPort" ]; then - echo_stderr "t3ClusterPort is required. " + if [ -z "$WLS_T3_CLUSTER_PORT" ]; then + echo_stderr "WLS_T3_CLUSTER_PORT is required. " usage 1 fi - if [ -z "$wlsJavaOption" ]; then - echo_stderr "wlsJavaOption is required. " + if [ -z "$WLS_JAVA_OPTIONS" ]; then + echo_stderr "WLS_JAVA_OPTIONS is required. " usage 1 fi - if [[ "${wlsJavaOption}" == "null" ]];then - wlsJavaOption="" + if [[ "${WLS_JAVA_OPTIONS}" == "null" ]];then + WLS_JAVA_OPTIONS="" + fi + + if [[ "${USE_ORACLE_IMAGE,,}" == "${constFalse}" ]] && [ -z "$USER_PROVIDED_IMAGE_PATH" ]; then + echo_stderr "USER_PROVIDED_IMAGE_PATH is required. " + usage 1 fi } @@ -221,6 +238,18 @@ function validate_status() { fi } +function get_wls_operator_version() { + local wlsToolingFamilyJsonFile=weblogic_tooling_family.json + # download the json file that wls operator version from weblogic-azure repo. + curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -fsL "${gitUrl4WLSToolingFamilyJsonFile}" -o ${wlsToolingFamilyJsonFile} + if [ $? -eq 0 ]; then + wlsOptVersion=$(cat ${wlsToolingFamilyJsonFile} | jq ".items[] | select(.key==\"WKO\") | .version" | tr -d "\"") + echo "WKO version: ${wlsOptVersion}" + else + echo "WKO version: latest" + fi +} + # Install latest kubectl and Helm function install_utilities() { if [ -d "apps" ]; then @@ -237,14 +266,14 @@ function install_utilities() { validate_status ${ret} # Install Helm - browserURL=$(curl -m ${curlMaxTime} -s https://api.github.com/repos/helm/helm/releases/latest | + browserURL=$(curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -s https://api.github.com/repos/helm/helm/releases/latest | grep "browser_download_url.*linux-amd64.tar.gz.asc" | cut -d : -f 2,3 | tr -d \") helmLatestVersion=${browserURL#*download\/} helmLatestVersion=${helmLatestVersion%%\/helm*} helmPackageName=helm-${helmLatestVersion}-linux-amd64.tar.gz - curl -m ${curlMaxTime} -fL https://get.helm.sh/${helmPackageName} -o /tmp/${helmPackageName} + curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -fL https://get.helm.sh/${helmPackageName} -o /tmp/${helmPackageName} tar -zxvf /tmp/${helmPackageName} -C /tmp mv /tmp/linux-amd64/helm /usr/local/bin/helm echo "Helm version" @@ -256,11 +285,6 @@ function install_utilities() { validate_status ${ret} } -# Connect to AKS cluster -function connect_aks_cluster() { - az aks get-credentials --resource-group ${aksClusterRGName} --name ${aksClusterName} --overwrite-existing -} - # remove the operator if it is not running. function uninstall_operator() { echo "remove operator" @@ -320,14 +344,24 @@ function install_wls_operator() { fi echo "install the operator" - helm install ${wlsOptRelease} weblogic-operator/weblogic-operator \ + if [[ -n "${wlsOptVersion}" ]]; then + helm install ${wlsOptRelease} weblogic-operator/weblogic-operator \ + --namespace ${wlsOptNameSpace} \ + --set serviceAccount=${wlsOptSA} \ + --set "enableClusterRoleBinding=true" \ + --set "domainNamespaceSelectionStrategy=LabelSelector" \ + --set "domainNamespaceLabelSelector=weblogic-operator\=enabled" \ + --version ${wlsOptVersion} \ + --wait + else + helm install ${wlsOptRelease} weblogic-operator/weblogic-operator \ --namespace ${wlsOptNameSpace} \ --set serviceAccount=${wlsOptSA} \ --set "enableClusterRoleBinding=true" \ --set "domainNamespaceSelectionStrategy=LabelSelector" \ --set "domainNamespaceLabelSelector=weblogic-operator\=enabled" \ - --version ${wlsOptVersion} \ --wait + fi validate_status "Installing WLS operator." @@ -341,10 +375,16 @@ function install_wls_operator() { # Query ACR login server, username, password function query_acr_credentials() { - azureACRServer=$(az acr show -n $acrName --query 'loginServer' -o tsv) - validate_status ${azureACRServer} - azureACRUserName=$(az acr credential show -n $acrName --query 'username' -o tsv) - azureACRPassword=$(az acr credential show -n $acrName --query 'passwords[0].value' -o tsv) + # to mitigate error in https://learn.microsoft.com/en-us/answers/questions/1188413/the-resource-with-name-name-and-type-microsoft-con + az provider register -n Microsoft.ContainerRegistry + + ACR_LOGIN_SERVER=$(az acr show -n $ACR_NAME -g ${ACR_RESOURCEGROUP_NAME} --query 'loginServer' -o tsv) + validate_status ${ACR_LOGIN_SERVER} + + ACR_USER_NAME=$(az acr credential show -n $ACR_NAME -g ${ACR_RESOURCEGROUP_NAME} --query 'username' -o tsv) + validate_status "Query ACR credentials." + + ACR_SHIBBOLETH=$(az acr credential show -n $ACR_NAME -g ${ACR_RESOURCEGROUP_NAME} --query 'passwords[0].value' -o tsv) validate_status "Query ACR credentials." } @@ -356,31 +396,21 @@ function query_acr_credentials() { function build_docker_image() { echo "build a new image including the new applications" chmod ugo+x $scriptDir/createVMAndBuildImage.sh - echo $azureACRPassword $ocrSSOPSW | - bash $scriptDir/createVMAndBuildImage.sh \ - $currentResourceGroup \ - $wlsImageTag \ - $azureACRServer \ - $azureACRUserName \ - $newImageTag \ - "$appPackageUrls" \ - $ocrSSOUser \ - $wlsClusterSize \ - $enableCustomSSL \ - "$scriptURL" \ - ${enableAdminT3Tunneling} \ - ${enableClusterT3Tunneling} - - az acr repository show -n ${acrName} --image aks-wls-images:${newImageTag} + echo ${ACR_SHIBBOLETH} | bash $scriptDir/createVMAndBuildImage.sh $newImageTag ${ACR_LOGIN_SERVER} ${ACR_USER_NAME} + + # to mitigate error in https://learn.microsoft.com/en-us/answers/questions/1188413/the-resource-with-name-name-and-type-microsoft-con + az provider register -n Microsoft.ContainerRegistry + + az acr repository show -n ${ACR_NAME} --image aks-wls-images:${newImageTag} if [ $? -ne 0 ]; then - echo "Failed to create image ${azureACRServer}/aks-wls-images:${newImageTag}" + echo "Failed to create image ${ACR_LOGIN_SERVER}/aks-wls-images:${newImageTag}" exit 1 fi } function create_source_folder_for_certificates() { mntRoot="/wls" - mntPath="$mntRoot/$storageAccountName/$azFileShareName" + mntPath="$mntRoot/$STORAGE_ACCOUNT_NAME/$azFileShareName" mkdir -p $mntPath @@ -396,42 +426,15 @@ function create_source_folder_for_certificates() { } function validate_ssl_keystores() { - #validate if identity keystore has entry - ${JAVA_HOME}/bin/keytool -list -v \ - -keystore ${mntPath}/$wlsIdentityKeyStoreFileName \ - -storepass $wlsIdentityPsw \ - -storetype $wlsIdentityType | - grep 'Entry type:' | - grep 'PrivateKeyEntry' - - validate_status "Validate Identity Keystore." - - #validate if trust keystore has entry - ${JAVA_HOME}/bin/keytool -list -v \ - -keystore ${mntPath}/${wlsTrustKeyStoreFileName} \ - -storepass $wlsTrustPsw \ - -storetype $wlsTrustType | - grep 'Entry type:' | - grep 'trustedCertEntry' - - validate_status "Validate Trust Keystore." - #validate if trust keystore has entry - ${JAVA_HOME}/bin/keytool -list -v \ - -keystore ${mntPath}/${wlsTrustKeyStoreFileName} \ - -storepass $wlsTrustPsw \ - -storetype jks | - grep 'Entry type:' | - grep 'trustedCertEntry' - ${JAVA_HOME}/bin/keytool -list -v \ -keystore ${mntPath}/${wlsTrustKeyStoreJKSFileName} \ - -storepass $wlsTrustPsw \ + -storepass $WLS_SSL_TRUST_SHIBBOLETH \ -storetype jks | grep 'Entry type:' | grep 'trustedCertEntry' - validate_status "Validate Trust Keystore." + validate_status "validate Trust Keystore." echo "Validate SSL key stores successfull !!" } @@ -441,7 +444,7 @@ function upload_certificates_to_fileshare() { sasTokenEnd=$(date -d@"$expiryData" -u '+%Y-%m-%dT%H:%MZ') sasToken=$(az storage share generate-sas \ --name ${azFileShareName} \ - --account-name ${storageAccountName} \ + --account-name ${STORAGE_ACCOUNT_NAME} \ --https-only \ --permissions dlrw \ --expiry $sasTokenEnd -o tsv) @@ -451,13 +454,13 @@ function upload_certificates_to_fileshare() { utility_create_directory_to_fileshare \ ${fsSecurityDirName} \ ${azFileShareName} \ - ${storageAccountName} \ + ${STORAGE_ACCOUNT_NAME} \ $sasToken echo "upload $wlsIdentityKeyStoreFileName" utility_upload_file_to_fileshare \ ${azFileShareName} \ - ${storageAccountName} \ + ${STORAGE_ACCOUNT_NAME} \ "$wlsIdentityKeyStoreFileName" \ ${mntPath}/$wlsIdentityKeyStoreFileName \ $sasToken @@ -465,7 +468,7 @@ function upload_certificates_to_fileshare() { echo "upload $wlsTrustKeyStoreFileName" utility_upload_file_to_fileshare \ ${azFileShareName} \ - ${storageAccountName} \ + ${STORAGE_ACCOUNT_NAME} \ "$wlsTrustKeyStoreFileName" \ ${mntPath}/$wlsTrustKeyStoreFileName \ $sasToken @@ -473,7 +476,7 @@ function upload_certificates_to_fileshare() { echo "upload $wlsTrustKeyStoreJKSFileName" utility_upload_file_to_fileshare \ ${azFileShareName} \ - ${storageAccountName} \ + ${STORAGE_ACCOUNT_NAME} \ "$wlsTrustKeyStoreJKSFileName" \ ${mntPath}/${wlsTrustKeyStoreJKSFileName} \ $sasToken @@ -482,24 +485,24 @@ function upload_certificates_to_fileshare() { function output_ssl_keystore() { echo "Custom SSL is enabled. Storing CertInfo as files..." #decode cert data once again as it would got base64 encoded - echo "$wlsIdentityData" | base64 -d >${mntPath}/$wlsIdentityKeyStoreFileName - echo "$wlsTrustData" | base64 -d >${mntPath}/$wlsTrustKeyStoreFileName + echo "$WLS_SSL_IDENTITY_DATA" | base64 -d >${mntPath}/$wlsIdentityKeyStoreFileName + echo "$WLS_SSL_TRUST_DATA" | base64 -d >${mntPath}/$wlsTrustKeyStoreFileName # export jks file # -Dweblogic.security.SSL.trustedCAKeyStorePassPhrase for PKCS12 is not working correctly # we neet to convert PKCS12 file to JKS file and specify in domain.yaml via -Dweblogic.security.SSL.trustedCAKeyStore - if [[ "${wlsTrustType,,}" != "jks" ]]; then + if [[ "${WLS_SSL_TRUST_TYPE,,}" != "jks" ]]; then ${JAVA_HOME}/bin/keytool -importkeystore \ -srckeystore ${mntPath}/${wlsTrustKeyStoreFileName} \ - -srcstoretype ${wlsTrustType} \ - -srcstorepass ${wlsTrustPsw} \ + -srcstoretype ${WLS_SSL_TRUST_TYPE} \ + -srcstorepass ${WLS_SSL_TRUST_SHIBBOLETH} \ -destkeystore ${mntPath}/${wlsTrustKeyStoreJKSFileName} \ -deststoretype jks \ - -deststorepass ${wlsTrustPsw} + -deststorepass ${WLS_SSL_TRUST_SHIBBOLETH} validate_status "Export trust JKS file." else - echo "$wlsTrustData" | base64 -d >${mntPath}/${wlsTrustKeyStoreJKSFileName} + echo "$WLS_SSL_TRUST_DATA" | base64 -d >${mntPath}/${wlsTrustKeyStoreJKSFileName} fi } @@ -509,8 +512,8 @@ function output_ssl_keystore() { # * Create PVC function create_pv() { echo "check if pv/pvc have been created." - pvcName=${wlsDomainUID}-pvc-azurefile - pvName=${wlsDomainUID}-pv-azurefile + pvcName=${WLS_DOMAIN_UID}-pvc-azurefile + pvName=${WLS_DOMAIN_UID}-pv-azurefile ret=$(kubectl -n ${wlsDomainNS} get pvc ${pvcName} | grep "Bound") if [ -n "$ret" ]; then @@ -519,23 +522,23 @@ function create_pv() { # the offer will create a new storage account in a new resource group. # remove the new storage account. currentStorageAccount=$(kubectl get pv ${pvName} -o json | jq '. | .metadata.labels.storageAccount' | tr -d "\"") - if [[ "${currentStorageAccount}" != "${storageAccountName}" ]]; then + if [[ "${currentStorageAccount}" != "${STORAGE_ACCOUNT_NAME}" ]]; then echo "the cluster is bound to pv on storage account ${currentStorageAccount}" - az storage account delete -n ${storageAccountName} -g $currentResourceGroup -y - storageAccountName=${currentStorageAccount} # update storage account name + az storage account delete -n ${STORAGE_ACCOUNT_NAME} -g $CURRENT_RESOURCEGROUP_NAME -y + STORAGE_ACCOUNT_NAME=${currentStorageAccount} # update storage account name echo "query storage account resource group" - storageResourceGroup=$(az storage account show --name ${storageAccountName} | jq '.resourceGroup' | tr -d "\"") - echo "resource group that contains storage account ${storageAccountName} is ${storageResourceGroup}" + storageResourceGroup=$(az storage account show --name ${STORAGE_ACCOUNT_NAME} | jq '.resourceGroup' | tr -d "\"") + echo "resource group that contains storage account ${STORAGE_ACCOUNT_NAME} is ${storageResourceGroup}" fi return fi echo "create pv/pvc." - export storageAccountKey=$(az storage account keys list --resource-group $storageResourceGroup --account-name $storageAccountName --query "[0].value" -o tsv) + export storageAccountKey=$(az storage account keys list --resource-group $storageResourceGroup --account-name $STORAGE_ACCOUNT_NAME --query "[0].value" -o tsv) export azureSecretName="azure-secret" kubectl -n ${wlsDomainNS} create secret generic ${azureSecretName} \ - --from-literal=azurestorageaccountname=${storageAccountName} \ + --from-literal=azurestorageaccountname=${STORAGE_ACCOUNT_NAME} \ --from-literal=azurestorageaccountkey=${storageAccountKey} # generate pv configurations @@ -544,14 +547,15 @@ function create_pv() { sed -i -e "s:@NAMESPACE@:${wlsDomainNS}:g" ${customPVYaml} sed -i -e "s:@PV_NAME@:${pvName}:g" ${customPVYaml} sed -i -e "s:@PVC_NAME@:${pvcName}:g" ${customPVYaml} - sed -i -e "s:@STORAGE_ACCOUNT@:${storageAccountName}:g" ${customPVYaml} + sed -i -e "s:@STORAGE_ACCOUNT@:${STORAGE_ACCOUNT_NAME}:g" ${customPVYaml} + sed -i -e "s:@FILE_SHARE_NAME@:${FILE_SHARE_NAME}:g" ${customPVYaml} # generate pv configurations customPVCYaml=${scriptDir}/pvc.yaml cp ${scriptDir}/pvc.yaml.template ${customPVCYaml} sed -i -e "s:@NAMESPACE@:${wlsDomainNS}:g" ${customPVCYaml} sed -i -e "s:@PVC_NAME@:${pvcName}:g" ${customPVCYaml} - sed -i -e "s:@STORAGE_ACCOUNT@:${storageAccountName}:g" ${customPVCYaml} + sed -i -e "s:@STORAGE_ACCOUNT@:${STORAGE_ACCOUNT_NAME}:g" ${customPVCYaml} kubectl apply -f ${customPVYaml} utility_check_pv_state ${pvName} "Available" ${checkPVStateMaxAttempt} ${checkPVStateInterval} @@ -566,10 +570,10 @@ function create_pv() { } function wait_for_pod_completed() { - echo "Waiting for $((appReplicas + 1)) pods are running." + echo "Waiting for $((WLS_APP_REPLICAS + 1)) pods are running." utility_wait_for_pod_completed \ - ${appReplicas} \ + ${WLS_APP_REPLICAS} \ "${wlsDomainNS}" \ ${checkPodStatusMaxAttemps} \ ${checkPodStatusInterval} @@ -578,12 +582,12 @@ function wait_for_pod_completed() { function wait_for_image_update_completed() { # Make sure all of the pods are updated with new image. # Assumption: we have only one cluster currently. - acrImagePath=${azureACRServer}/aks-wls-images:${newImageTag} - echo "Waiting for $((appReplicas + 1)) new pods created with image ${acrImagePath}" + acrImagePath=${ACR_LOGIN_SERVER}/aks-wls-images:${newImageTag} + echo "Waiting for $((WLS_APP_REPLICAS + 1)) new pods created with image ${acrImagePath}" utility_wait_for_image_update_completed \ "${acrImagePath}" \ - ${appReplicas} \ + ${WLS_APP_REPLICAS} \ "${wlsDomainNS}" \ ${checkPodStatusMaxAttemps} \ ${checkPodStatusInterval} @@ -608,26 +612,26 @@ function create_domain_namespace() { kubectl -n ${wlsDomainNS} create secret generic \ ${kubectlWLSCredentialName} \ - --from-literal=username=${wlsUserName} \ - --from-literal=password=${wlsPassword} + --from-literal=username=${WLS_ADMIN_USER_NAME} \ + --from-literal=password=${WLS_ADMIN_SHIBBOLETH} - kubectl -n ${wlsDomainNS} label secret ${kubectlWLSCredentialName} weblogic.domainUID=${wlsDomainUID} + kubectl -n ${wlsDomainNS} label secret ${kubectlWLSCredentialName} weblogic.domainUID=${WLS_DOMAIN_UID} kubectl -n ${wlsDomainNS} create secret generic ${kubectlWDTEncryptionSecret} \ - --from-literal=password=${wdtRuntimePassword} - kubectl -n ${wlsDomainNS} label secret ${kubectlWDTEncryptionSecret} weblogic.domainUID=${wlsDomainUID} + --from-literal=password=${WLS_WDT_RUNTIME_PSW} + kubectl -n ${wlsDomainNS} label secret ${kubectlWDTEncryptionSecret} weblogic.domainUID=${WLS_DOMAIN_UID} kubectl create secret docker-registry ${kubectlSecretForACR} \ - --docker-server=${azureACRServer} \ - --docker-username=${azureACRUserName} \ - --docker-password=${azureACRPassword} \ + --docker-server=${ACR_LOGIN_SERVER} \ + --docker-username=${ACR_USER_NAME} \ + --docker-password=${ACR_SHIBBOLETH} \ -n ${wlsDomainNS} - kubectl -n ${wlsDomainNS} label secret ${kubectlSecretForACR} weblogic.domainUID=${wlsDomainUID} + kubectl -n ${wlsDomainNS} label secret ${kubectlSecretForACR} weblogic.domainUID=${WLS_DOMAIN_UID} } function parsing_ssl_certs_and_create_ssl_secret() { - if [[ "${enableCustomSSL,,}" == "${constTrue}" ]]; then + if [[ "${ENABLE_CUSTOM_SSL,,}" == "${constTrue}" ]]; then # use default Java, if no, install open jdk 11. # why not use Microsoft open jdk? No apk installation package! export JAVA_HOME=/usr/lib/jvm/default-jvm/ @@ -649,17 +653,17 @@ function parsing_ssl_certs_and_create_ssl_secret() { fi echo "create secret ${kubectlWLSSSLCredentialsName}" kubectl -n ${wlsDomainNS} create secret generic ${kubectlWLSSSLCredentialsName} \ - --from-literal=sslidentitykeyalias=${wlsIdentityAlias} \ - --from-literal=sslidentitykeypassword=${wlsIdentityKeyPsw} \ + --from-literal=sslidentitykeyalias=${WLS_SSL_PRIVATE_KEY_ALIAS} \ + --from-literal=sslidentitykeypassword=${WLS_SSL_PRIVATE_KEY_SHIBBOLETH} \ --from-literal=sslidentitystorepath=${sharedPath}/$wlsIdentityKeyStoreFileName \ - --from-literal=sslidentitystorepassword=${wlsIdentityPsw} \ - --from-literal=sslidentitystoretype=${wlsIdentityType} \ + --from-literal=sslidentitystorepassword=${WLS_SSL_IDENTITY_SHIBBOLETH} \ + --from-literal=sslidentitystoretype=${WLS_SSL_IDENTITY_TYPE} \ --from-literal=ssltruststorepath=${sharedPath}/${wlsTrustKeyStoreFileName} \ - --from-literal=ssltruststoretype=${wlsTrustType} \ - --from-literal=ssltruststorepassword=${wlsTrustPsw} + --from-literal=ssltruststoretype=${WLS_SSL_TRUST_TYPE} \ + --from-literal=ssltruststorepassword=${WLS_SSL_TRUST_SHIBBOLETH} - kubectl -n ${wlsDomainNS} label secret ${kubectlWLSSSLCredentialsName} weblogic.domainUID=${wlsDomainUID} - javaOptions=" -Dweblogic.security.SSL.ignoreHostnameVerification=true -Dweblogic.security.SSL.trustedCAKeyStore=${sharedPath}/${wlsTrustKeyStoreJKSFileName} ${javaOptions}" + kubectl -n ${wlsDomainNS} label secret ${kubectlWLSSSLCredentialsName} weblogic.domainUID=${WLS_DOMAIN_UID} + javaOptions=" -Dweblogic.security.SSL.ignoreHostnameVerification=true -Dweblogic.security.SSL.trustedCAKeyStore=${sharedPath}/${wlsTrustKeyStoreJKSFileName} -Dweblogic.security.SSL.trustedCAKeyStorePassPhrase=${WLS_SSL_TRUST_SHIBBOLETH} ${javaOptions}" fi } @@ -671,7 +675,7 @@ function parsing_ssl_certs_and_create_ssl_secret() { # * Deploy WebLogic domain using image in ACR # * Wait for the domain completed function setup_wls_domain() { - export javaOptions=${wlsJavaOption} + export javaOptions=${WLS_JAVA_OPTIONS} if [[ "${enableClusterT3Channel,,}" == "true" ]] || [[ "${enableAdminT3Channel,,}" == "true" ]]; then # for remote t3/t3s access. # refer to https://oracle.github.io/weblogic-kubernetes-operator/faq/external-clients/#enabling-unknown-host-access @@ -682,7 +686,7 @@ function setup_wls_domain() { create_domain_namespace echo "constTrue": "${constTrue}" - if [[ "${enablePV,,}" == "${constTrue}" ]]; then + if [[ "${ENABLE_PV,,}" == "${constTrue}" ]]; then echo "start to create pv/pvc. " create_pv fi @@ -701,45 +705,19 @@ function setup_wls_domain() { customDomainYaml=${scriptDir}/custom-domain.yaml if [[ "${updateNamepace}" == "${constTrue}" ]]; then - echo "start to update domain ${wlsDomainUID}" + echo "start to update domain ${WLS_DOMAIN_UID}" chmod ugo+x $scriptDir/updateDomainConfig.sh bash $scriptDir/updateDomainConfig.sh \ ${customDomainYaml} \ - ${appReplicas} \ - ${wlsCPU} \ - ${wlsDomainUID} \ - ${wlsDomainName} \ - "${azureACRServer}/aks-wls-images:${newImageTag}" \ - ${wlsMemory} \ - ${managedServerPrefix} \ - ${enableCustomSSL} \ - ${enablePV} \ - ${enableAdminT3Tunneling} \ - ${enableClusterT3Tunneling} \ - ${t3AdminPort} \ - ${t3ClusterPort} \ - ${constClusterName} \ + "${ACR_LOGIN_SERVER}/aks-wls-images:${newImageTag}" \ "${javaOptions}" else - echo "start to create domain ${wlsDomainUID}" + echo "start to create domain ${WLS_DOMAIN_UID}" # generate domain yaml chmod ugo+x $scriptDir/genDomainConfig.sh bash $scriptDir/genDomainConfig.sh \ ${customDomainYaml} \ - ${appReplicas} \ - ${wlsCPU} \ - ${wlsDomainUID} \ - ${wlsDomainName} \ - "${azureACRServer}/aks-wls-images:${newImageTag}" \ - ${wlsMemory} \ - ${managedServerPrefix} \ - ${enableCustomSSL} \ - ${enablePV} \ - ${enableAdminT3Tunneling} \ - ${enableClusterT3Tunneling} \ - ${t3AdminPort} \ - ${t3ClusterPort} \ - ${constClusterName} \ + "${ACR_LOGIN_SERVER}/aks-wls-images:${newImageTag}" \ "${javaOptions}" fi @@ -757,71 +735,39 @@ export scriptDir="$(cd "$(dirname "${script}")" && pwd)" source ${scriptDir}/common.sh source ${scriptDir}/utility.sh -export ocrSSOUser=$1 -export aksClusterRGName=$2 -export aksClusterName=$3 -export wlsImageTag=$4 -export acrName=$5 -export wlsDomainName=$6 -export wlsDomainUID=$7 -export wlsUserName=$8 -export wlsCPU=$9 -export wlsMemory=${10} -export managedServerPrefix=${11} -export appReplicas=${12} -export appPackageUrls=${13} -export currentResourceGroup=${14} -export scriptURL=${15} -export storageAccountName=${16} -export wlsClusterSize=${17} -export enableCustomSSL=${18} -export wlsIdentityData=${19} -export wlsIdentityType=${20} -export wlsIdentityAlias=${21} -export wlsTrustData=${22} -export wlsTrustType=${23} -export enablePV=${24} -export enableAdminT3Tunneling=${25} -export enableClusterT3Tunneling=${26} -export t3AdminPort=${27} -export t3ClusterPort=${28} -export wlsJavaOption=${29} - export adminServerName="admin-server" -export azFileShareName="weblogic" +export azFileShareName=${FILE_SHARE_NAME} export exitCode=0 export kubectlSecretForACR="regsecret" -export kubectlWDTEncryptionSecret="${wlsDomainUID}-runtime-encryption-secret" -export kubectlWLSCredentialName="${wlsDomainUID}-weblogic-credentials" -export kubectlWLSSSLCredentialsName="${wlsDomainUID}-weblogic-ssl-credentials" +export kubectlWDTEncryptionSecret="${WLS_DOMAIN_UID}-runtime-encryption-secret" +export kubectlWLSCredentialName="${WLS_DOMAIN_UID}-weblogic-credentials" +export kubectlWLSSSLCredentialsName="${WLS_DOMAIN_UID}-weblogic-ssl-credentials" export newImageTag=$(date +%s) export operatorName="weblogic-operator" # seconds export sasTokenValidTime=3600 -export storageFileShareName="weblogic" -export storageResourceGroup=${currentResourceGroup} +export storageResourceGroup=${CURRENT_RESOURCEGROUP_NAME} export sharedPath="/shared" -export wlsDomainNS="${wlsDomainUID}-ns" +export wlsDomainNS="${WLS_DOMAIN_UID}-ns" export wlsOptHelmChart="https://oracle.github.io/weblogic-kubernetes-operator/charts" export wlsOptNameSpace="weblogic-operator-ns" export wlsOptRelease="weblogic-operator" export wlsOptSA="weblogic-operator-sa" -export wlsOptVersion="3.2.5" export wlsIdentityKeyStoreFileName="security/identity.keystore" export wlsTrustKeyStoreFileName="security/trust.keystore" export wlsTrustKeyStoreJKSFileName="security/trust.jks" -read_sensitive_parameters_from_stdin - validate_input +get_wls_operator_version + install_utilities query_acr_credentials build_docker_image -connect_aks_cluster +connect_aks $AKS_CLUSTER_NAME $AKS_CLUSTER_RESOURCEGROUP_NAME install_wls_operator diff --git a/weblogic-azure-aks/src/main/arm/scripts/updateApplications.sh b/weblogic-azure-aks/src/main/arm/scripts/updateApplications.sh index 4db5be666..b71c02dc0 100644 --- a/weblogic-azure-aks/src/main/arm/scripts/updateApplications.sh +++ b/weblogic-azure-aks/src/main/arm/scripts/updateApplications.sh @@ -1,30 +1,26 @@ -# Copyright (c) 2021, Oracle Corporation and/or its affiliates. +# Copyright (c) 2021, 2024, Oracle Corporation and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. echo "Script ${0} starts" -# read from stdin -function read_sensitive_parameters_from_stdin() { - read ocrSSOPSW -} - function usage() { usage=$(cat <<-END -Usage: -echo | - ./updateApplications.sh - - - - - - - - - - - - +Specify the following ENV variables: +ACR_NAME +AKS_CLUSTER_NAME +AKS_CLUSTER_RESOURCEGROUP_NAME +CURRENT_RESOURCEGROUP_NAME +ORACLE_ACCOUNT_NAME +ORACLE_ACCOUNT_SHIBBOLETH +STORAGE_ACCOUNT_NAME +STORAGE_ACCOUNT_CONTAINER_NAME +SCRIPT_LOCATION +USE_ORACLE_IMAGE +USER_PROVIDED_IMAGE_PATH +WLS_APP_PACKAGE_URLS +WLS_DOMAIN_NAME +WLS_DOMAIN_UID +WLS_IMAGE_TAG END ) echo_stdout "${usage}" @@ -36,89 +32,91 @@ END #Function to validate input function validate_input() { - if [[ -z "$ocrSSOUser" || -z "${ocrSSOPSW}" ]]; then + if [ -z "$USE_ORACLE_IMAGE" ]; then + echo_stderr "USER_PROVIDED_IMAGE_PATH is required. " + usage 1 + fi + + if [[ "${USE_ORACLE_IMAGE,,}" == "${constTrue}" ]] && [[ -z "$ORACLE_ACCOUNT_NAME" || -z "${ORACLE_ACCOUNT_SHIBBOLETH}" ]]; then echo_stderr "Oracle SSO account is required. " usage 1 fi - if [[ -z "$aksClusterRGName" || -z "${aksClusterName}" ]]; then + if [[ -z "$AKS_CLUSTER_RESOURCEGROUP_NAME" || -z "${AKS_CLUSTER_NAME}" ]]; then echo_stderr "AKS cluster name and resource group name are required. " usage 1 fi - if [ -z "$wlsImageTag" ]; then - echo_stderr "wlsImageTag is required. " + if [ -z "$WLS_IMAGE_TAG" ]; then + echo_stderr "WLS_IMAGE_TAG is required. " usage 1 fi - if [ -z "$acrName" ]; then - echo_stderr "acrName is required. " + if [ -z "$ACR_NAME" ]; then + echo_stderr "ACR_NAME is required. " usage 1 fi - if [ -z "$wlsDomainName" ]; then - echo_stderr "wlsDomainName is required. " + if [ -z "$WLS_DOMAIN_NAME" ]; then + echo_stderr "WLS_DOMAIN_NAME is required. " usage 1 fi - if [ -z "$wlsDomainUID" ]; then - echo_stderr "wlsDomainUID is required. " + if [ -z "$WLS_DOMAIN_UID" ]; then + echo_stderr "WLS_DOMAIN_UID is required. " usage 1 fi - if [ -z "$currentResourceGroup" ]; then - echo_stderr "currentResourceGroup is required. " + if [ -z "$CURRENT_RESOURCEGROUP_NAME" ]; then + echo_stderr "CURRENT_RESOURCEGROUP_NAME is required. " usage 1 fi - if [ -z "$appPackageUrls" ]; then - echo_stderr "appPackageUrls is required. " + if [ -z "$WLS_APP_PACKAGE_URLS" ]; then + echo_stderr "WLS_APP_PACKAGE_URLS is required. " usage 1 fi - if [ -z "$scriptURL" ]; then - echo_stderr "scriptURL is required. " + if [ -z "$SCRIPT_LOCATION" ]; then + echo_stderr "SCRIPT_LOCATION is required. " usage 1 fi - if [ -z "$appStorageAccountName" ]; then - echo_stderr "appStorageAccountName is required. " + if [ -z "$STORAGE_ACCOUNT_NAME" ]; then + echo_stderr "STORAGE_ACCOUNT_NAME is required. " usage 1 fi - if [ -z "$appContainerName" ]; then - echo_stderr "appContainerName is required. " + if [ -z "$STORAGE_ACCOUNT_CONTAINER_NAME" ]; then + echo_stderr "STORAGE_ACCOUNT_CONTAINER_NAME is required. " usage 1 fi -} -# Connect to AKS cluster -function connect_aks_cluster() { - az aks get-credentials \ - --resource-group ${aksClusterRGName} \ - --name ${aksClusterName} \ - --overwrite-existing + if [[ "${USE_ORACLE_IMAGE,,}" == "${constFalse}" ]] && [ -z "$USER_PROVIDED_IMAGE_PATH" ]; then + echo_stderr "USER_PROVIDED_IMAGE_PATH is required. " + usage 1 + fi } function query_wls_cluster_info(){ - wlsClusterSize=$(kubectl -n ${wlsDomainNS} get domain ${wlsDomainUID} -o json \ - | jq '. | .status.clusters[] | select(.clusterName == "'${wlsClusterName}'") | .maximumReplicas') - echo "cluster size: ${wlsClusterSize}" + WLS_CLUSTER_SIZE=$(kubectl -n ${wlsDomainNS} get domain ${WLS_DOMAIN_UID} -o json \ + | jq '. | .status.clusters[] | select(.clusterName == "'${constClusterName}'") | .maximumReplicas') + echo "cluster size: ${WLS_CLUSTER_SIZE}" - enableCustomSSL=${constFalse} - sslIdentityEnv=$(kubectl -n ${wlsDomainNS} get domain ${wlsDomainUID} -o json \ + ENABLE_CUSTOM_SSL=${constFalse} + sslIdentityEnv=$(kubectl -n ${wlsDomainNS} get domain ${WLS_DOMAIN_UID} -o json \ | jq '. | .spec.serverPod.env[] | select(.name=="'${sslIdentityEnvName}'")') if [ -n "${sslIdentityEnv}" ]; then - enableCustomSSL=${constTrue} + ENABLE_CUSTOM_SSL=${constTrue} fi } # Query ACR login server, username, password function query_acr_credentials() { - echo "query credentials of ACR ${acrName}" - azureACRServer=$(az acr show -n $acrName --query 'loginServer' -o tsv) - azureACRUserName=$(az acr credential show -n $acrName --query 'username' -o tsv) - azureACRPassword=$(az acr credential show -n $acrName --query 'passwords[0].value' -o tsv) + echo "query credentials of ACR ${ACR_NAME}" + ACR_LOGIN_SERVER=$(az acr show -n $ACR_NAME --query 'loginServer' -o tsv) + ACR_USER_NAME=$(az acr credential show -n $ACR_NAME --query 'username' -o tsv) + ACR_SHIBBOLETH=$(az acr credential show -n $ACR_NAME --query 'passwords[0].value' -o tsv) } function get_app_sas_url() { @@ -130,9 +128,9 @@ function get_app_sas_url() { appName=${args[${index}]} echo "app package file name: ${appName}" if [[ "$appName" == *".war" || "$appName" == *".ear" || "$appName" == *".jar" ]]; then - appSaSUrl=$(az storage blob url --container-name ${appContainerName} \ + appSaSUrl=$(az storage blob url --container-name ${STORAGE_ACCOUNT_CONTAINER_NAME} \ --name ${appName} \ - --account-name ${appStorageAccountName} \ + --account-name ${STORAGE_ACCOUNT_NAME} \ --sas-token ${sasToken} -o tsv) echo ${appSaSUrl} appSASUrlString="${appSASUrlString},${appSaSUrl}" @@ -142,32 +140,32 @@ function get_app_sas_url() { done # append urls - if [ "${appPackageUrls}" == "[]" ]; then - appPackageUrls="[${appSASUrlString:1:${#appSASUrlString}-1}]" # remove the beginning comma + if [ "${WLS_APP_PACKAGE_URLS}" == "[]" ]; then + WLS_APP_PACKAGE_URLS="[${appSASUrlString:1:${#appSASUrlString}-1}]" # remove the beginning comma else - appPackageUrls=$(echo "${appPackageUrls:1:${#appPackageUrls}-2}") # remove [] - appPackageUrls="[${appPackageUrls}${appSASUrlString}]" + WLS_APP_PACKAGE_URLS=$(echo "${WLS_APP_PACKAGE_URLS:1:${#WLS_APP_PACKAGE_URLS}-2}") # remove [] + WLS_APP_PACKAGE_URLS="[${WLS_APP_PACKAGE_URLS}${appSASUrlString}]" fi - echo $appPackageUrls + echo $WLS_APP_PACKAGE_URLS } function query_app_urls() { echo "check if the storage account exists." - ret=$(az storage account check-name --name ${appStorageAccountName} \ + ret=$(az storage account check-name --name ${STORAGE_ACCOUNT_NAME} \ | grep "AlreadyExists") if [ -z "$ret" ]; then - echo "${appStorageAccountName} does not exist." + echo "${STORAGE_ACCOUNT_NAME} does not exist." return fi - appList=$(az storage blob list --container-name ${appContainerName} \ - --account-name ${appStorageAccountName} \ + appList=$(az storage blob list --container-name ${STORAGE_ACCOUNT_CONTAINER_NAME} \ + --account-name ${STORAGE_ACCOUNT_NAME} \ | jq '.[] | .name' \ | tr -d "\"") if [ $? == 1 ]; then - echo "Failed to query application from ${appContainerName}" + echo "Failed to query application from ${STORAGE_ACCOUNT_CONTAINER_NAME}" return fi @@ -175,7 +173,7 @@ function query_app_urls() { sasTokenEnd=`date -d@"$expiryData" -u '+%Y-%m-%dT%H:%MZ'` sasToken=$(az storage account generate-sas \ --permissions r \ - --account-name ${appStorageAccountName} \ + --account-name ${STORAGE_ACCOUNT_NAME} \ --services b \ --resource-types sco \ --expiry $sasTokenEnd -o tsv) @@ -184,59 +182,46 @@ function query_app_urls() { } function build_docker_image() { - local enableAdminT3=${constFalse} - local enableClusterT3=${constFalse} - - local adminT3AddressEnv=$(kubectl -n ${wlsDomainNS} get domain ${wlsDomainUID} -o json \ + local adminT3AddressEnv=$(kubectl -n ${wlsDomainNS} get domain ${WLS_DOMAIN_UID} -o json \ | jq '. | .spec.serverPod.env[] | select(.name=="'${constAdminT3AddressEnvName}'")') if [ -n "${adminT3AddressEnv}" ]; then - enableAdminT3=${constTrue} + ENABLE_ADMIN_CUSTOM_T3=${constTrue} fi - local clusterT3AddressEnv=$(kubectl -n ${wlsDomainNS} get domain ${wlsDomainUID} -o json \ + local clusterT3AddressEnv=$(kubectl -n ${wlsDomainNS} get domain ${WLS_DOMAIN_UID} -o json \ | jq '. | .spec.serverPod.env[] | select(.name=="'${constClusterT3AddressEnvName}'")') if [ -n "${clusterT3AddressEnv}" ]; then - enableClusterT3=${constTrue} + ENABLE_CLUSTER_CUSTOM_T3=${constTrue} fi + export WLS_APP_PACKAGE_URLS=$(echo $WLS_APP_PACKAGE_URLS | base64 -w0) echo "build a new image including the new applications" chmod ugo+x $scriptDir/createVMAndBuildImage.sh - echo $azureACRPassword $ocrSSOPSW | \ - bash $scriptDir/createVMAndBuildImage.sh \ - $currentResourceGroup \ - $wlsImageTag \ - $azureACRServer \ - $azureACRUserName \ - $newImageTag \ - "$appPackageUrls" \ - $ocrSSOUser \ - $wlsClusterSize \ - $enableCustomSSL \ - "$scriptURL" \ - ${enableAdminT3} \ - ${enableClusterT3} - - az acr repository show -n ${acrName} --image aks-wls-images:${newImageTag} + echo ${ACR_SHIBBOLETH} \ + | bash $scriptDir/createVMAndBuildImage.sh $newImageTag ${ACR_LOGIN_SERVER} ${ACR_USER_NAME} + + az acr repository show -n ${ACR_NAME} --image aks-wls-images:${newImageTag} if [ $? -ne 0 ]; then - echo "Failed to create image ${azureACRServer}/aks-wls-images:${newImageTag}" + echo "Failed to create image ${ACR_LOGIN_SERVER}/aks-wls-images:${newImageTag}" exit 1 fi } function apply_new_image() { - acrImagePath="${azureACRServer}/aks-wls-images:${newImageTag}" - restartVersion=$(kubectl -n ${wlsDomainNS} get domain ${wlsDomainUID} '-o=jsonpath={.spec.restartVersion}') + acrImagePath="${ACR_LOGIN_SERVER}/aks-wls-images:${newImageTag}" + restartVersion=$(kubectl -n ${wlsDomainNS} get domain ${WLS_DOMAIN_UID} '-o=jsonpath={.spec.restartVersion}') # increase restart version restartVersion=$((restartVersion + 1)) - kubectl -n ${wlsDomainNS} patch domain ${wlsDomainUID} \ + kubectl -n ${wlsDomainNS} patch domain ${WLS_DOMAIN_UID} \ --type=json \ '-p=[{"op": "replace", "path": "/spec/restartVersion", "value": "'${restartVersion}'" }, {"op": "replace", "path": "/spec/image", "value": "'${acrImagePath}'" }]' } function wait_for_pod_completed() { # Make sure all of the pods are running. - replicas=$(kubectl -n ${wlsDomainNS} get domain ${wlsDomainUID} -o json \ - | jq '. | .spec.clusters[] | .replicas') + local clusterName=$(kubectl get cluster -n ${wlsDomainNS} -o json | jq -r '.items[0].metadata.name') + local replicas=$(kubectl -n ${wlsDomainNS} get cluster ${clusterName} -o json \ + | jq '. | .spec.replicas') utility_wait_for_pod_completed \ ${replicas} \ @@ -248,8 +233,9 @@ function wait_for_pod_completed() { function wait_for_image_update_completed() { # Make sure all of the pods are updated with new image. # Assumption: we have only one cluster currently. - replicas=$(kubectl -n ${wlsDomainNS} get domain ${wlsDomainUID} -o json \ - | jq '. | .spec.clusters[] | .replicas') + local clusterName=$(kubectl get cluster -n ${wlsDomainNS} -o json | jq -r '.items[0].metadata.name') + local replicas=$(kubectl -n ${wlsDomainNS} get cluster ${clusterName} -o json \ + | jq '. | .spec.replicas') utility_wait_for_image_update_completed \ "${acrImagePath}" \ @@ -277,33 +263,27 @@ export scriptDir="$(cd "$(dirname "${script}")" && pwd)" source ${scriptDir}/common.sh source ${scriptDir}/utility.sh -export ocrSSOUser=$1 -export aksClusterRGName=$2 -export aksClusterName=$3 -export wlsImageTag=$4 -export acrName=$5 -export wlsDomainName=$6 -export wlsDomainUID=$7 -export currentResourceGroup=$8 -export appPackageUrls=$9 -export scriptURL=${10} -export appStorageAccountName=${11} -export appContainerName=${12} - export newImageTag=$(date +%s) # seconds export sasTokenValidTime=3600 export sslIdentityEnvName="SSL_IDENTITY_PRIVATE_KEY_ALIAS" -export wlsClusterName="cluster-1" -export wlsDomainNS="${wlsDomainUID}-ns" +export wlsDomainNS="${WLS_DOMAIN_UID}-ns" + +# export ENV var that will be used in createVMAndBuildImage.sh +export ENABLE_ADMIN_CUSTOM_T3=${constFalse} +export ENABLE_CLUSTER_CUSTOM_T3=${constFalse} +export ENABLE_CUSTOM_SSL=${constFalse} +export WLS_CLUSTER_SIZE=5 +export URL_3RD_DATASOURCE=$(echo "[]" | base64) -read_sensitive_parameters_from_stdin +# Main script +set -Eo pipefail validate_input install_kubectl -connect_aks_cluster +connect_aks $AKS_CLUSTER_NAME $AKS_CLUSTER_RESOURCEGROUP_NAME query_wls_cluster_info diff --git a/weblogic-azure-aks/src/main/arm/scripts/updateDomainConfig.sh b/weblogic-azure-aks/src/main/arm/scripts/updateDomainConfig.sh index 86db0c86c..b2109c0ac 100644 --- a/weblogic-azure-aks/src/main/arm/scripts/updateDomainConfig.sh +++ b/weblogic-azure-aks/src/main/arm/scripts/updateDomainConfig.sh @@ -5,29 +5,16 @@ export script="${BASH_SOURCE[0]}" export scriptDir="$(cd "$(dirname "${script}")" && pwd)" export filePath=$1 -export replicas=$2 -export wlsCPU=$3 -export wlsDomainUID=$4 -export wlsDomainName=$5 -export wlsImagePath=$6 -export wlsMemory=$7 -export wlsManagedPrefix=$8 -export enableSSL=${9} -export enablePV=${10} -export enableAdminT3Tunneling=${11} -export enableClusterT3Tunneling=${12} -export t3AdminPort=${13} -export t3ClusterPort=${14} -export clusterName=${15} -export javaOptions=${16} - -export adminServiceUrl="${wlsDomainUID}-admin-server.${wlsDomainUID}-ns.svc.cluster.local" -export clusterServiceUrl="${wlsDomainUID}-cluster-${clusterName}.${wlsDomainUID}-ns.svc.cluster.local" -export wlsDomainNS="${wlsDomainUID}-ns" +export wlsImagePath=$2 +export javaOptions=$3 + +export adminServiceUrl="${WLS_DOMAIN_UID}-admin-server.${WLS_DOMAIN_UID}-ns.svc.cluster.local" +export clusterServiceUrl="${WLS_DOMAIN_UID}-cluster-${constClusterName}.${WLS_DOMAIN_UID}-ns.svc.cluster.local" +export wlsDomainNS="${WLS_DOMAIN_UID}-ns" # output the existing domain configuration export previousConfig=${scriptDir}/previousDomain.json -kubectl -n ${wlsDomainNS} get domain ${wlsDomainUID} -o json >${previousConfig} +kubectl -n ${wlsDomainNS} get domain ${WLS_DOMAIN_UID} -o json >${previousConfig} # query logHomeEnabled logHomeEnabled=$(cat ${previousConfig} | jq '. | .spec.logHomeEnabled') @@ -47,13 +34,13 @@ cat <$filePath # in https://github.com/oracle/weblogic-kubernetes-operator. # This is an example of how to define a Domain resource. # -apiVersion: "weblogic.oracle/v8" +apiVersion: "weblogic.oracle/v9" kind: Domain metadata: - name: "${wlsDomainUID}" + name: "${WLS_DOMAIN_UID}" namespace: "${wlsDomainNS}" labels: - weblogic.domainUID: "${wlsDomainUID}" + weblogic.domainUID: "${WLS_DOMAIN_UID}" spec: # Set to 'FromModel' to indicate 'Model in Image'. @@ -61,7 +48,7 @@ spec: # The WebLogic Domain Home, this must be a location within # the image for 'Model in Image' domains. - domainHome: /u01/domains/${wlsDomainUID} + domainHome: /u01/domains/${WLS_DOMAIN_UID} # The WebLogic Server Docker image that the Operator uses to start the domain image: "${wlsImagePath}" @@ -76,7 +63,7 @@ spec: # Identify which Secret contains the WebLogic Admin credentials, # the secret must contain 'username' and 'password' fields. webLogicCredentialsSecret: - name: "${wlsDomainUID}-weblogic-credentials" + name: "${WLS_DOMAIN_UID}-weblogic-credentials" # Whether to include the WebLogic Server stdout in the pod's stdout, default is true includeServerOutInPodLog: true @@ -104,72 +91,72 @@ cat <>$filePath serverPod: resources: requests: - cpu: "${wlsCPU}" - memory: "${wlsMemory}" + cpu: "${WLS_RESOURCE_REQUEST_CPU}" + memory: "${WLS_RESOURCE_REQUEST_MEMORY}" # Optional new or overridden environment variables for the domain's pods # - This sample uses CUSTOM_DOMAIN_NAME in its image model file # to set the Weblogic domain name env: EOF -if [[ "${enableSSL,,}" == "true" ]]; then +if [[ "${ENABLE_CUSTOM_SSL,,}" == "true" ]]; then cat <>$filePath - name: SSL_IDENTITY_PRIVATE_KEY_ALIAS valueFrom: secretKeyRef: key: sslidentitykeyalias - name: ${wlsDomainUID}-weblogic-ssl-credentials + name: ${WLS_DOMAIN_UID}-weblogic-ssl-credentials - name: SSL_IDENTITY_PRIVATE_KEY_PSW valueFrom: secretKeyRef: key: sslidentitykeypassword - name: ${wlsDomainUID}-weblogic-ssl-credentials + name: ${WLS_DOMAIN_UID}-weblogic-ssl-credentials - name: SSL_IDENTITY_PRIVATE_KEYSTORE_PATH valueFrom: secretKeyRef: key: sslidentitystorepath - name: ${wlsDomainUID}-weblogic-ssl-credentials + name: ${WLS_DOMAIN_UID}-weblogic-ssl-credentials - name: SSL_IDENTITY_PRIVATE_KEYSTORE_TYPE valueFrom: secretKeyRef: key: sslidentitystoretype - name: ${wlsDomainUID}-weblogic-ssl-credentials + name: ${WLS_DOMAIN_UID}-weblogic-ssl-credentials - name: SSL_IDENTITY_PRIVATE_KEYSTORE_PSW valueFrom: secretKeyRef: key: sslidentitystorepassword - name: ${wlsDomainUID}-weblogic-ssl-credentials + name: ${WLS_DOMAIN_UID}-weblogic-ssl-credentials - name: SSL_TRUST_KEYSTORE_PATH valueFrom: secretKeyRef: key: ssltruststorepath - name: ${wlsDomainUID}-weblogic-ssl-credentials + name: ${WLS_DOMAIN_UID}-weblogic-ssl-credentials - name: SSL_TRUST_KEYSTORE_TYPE valueFrom: secretKeyRef: key: ssltruststoretype - name: ${wlsDomainUID}-weblogic-ssl-credentials + name: ${WLS_DOMAIN_UID}-weblogic-ssl-credentials - name: SSL_TRUST_KEYSTORE_PSW valueFrom: secretKeyRef: key: ssltruststorepassword - name: ${wlsDomainUID}-weblogic-ssl-credentials + name: ${WLS_DOMAIN_UID}-weblogic-ssl-credentials EOF fi -if [[ "${enableAdminT3Tunneling,,}" == "true" ]]; then +if [[ "${ENABLE_ADMIN_CUSTOM_T3,,}" == "true" ]]; then cat <>$filePath - name: T3_TUNNELING_ADMIN_PORT - value: "${t3AdminPort}" + value: "${WLS_T3_ADMIN_PORT}" - name: T3_TUNNELING_ADMIN_ADDRESS value: "${adminServiceUrl}" EOF fi -if [[ "${enableClusterT3Tunneling,,}" == "true" ]]; then +if [[ "${ENABLE_CLUSTER_CUSTOM_T3,,}" == "true" ]]; then cat <>$filePath - name: T3_TUNNELING_CLUSTER_PORT - value: "${t3ClusterPort}" + value: "${WLS_T3_CLUSTER_PORT}" - name: T3_TUNNELING_CLUSTER_ADDRESS value: "${clusterServiceUrl}" EOF @@ -182,7 +169,7 @@ while [ $index -lt ${envLength} ]; do index=$((index+1)) if [[ "${envItemName}" == "JAVA_OPTIONS" ]];then - envItemValue="\"-Dweblogic.StdoutDebugEnabled=false ${javaOptions}\"" + envItemValue="\"${constDefaultJavaOptions} ${javaOptions}\"" fi # do not copy value from SSL_ env @@ -207,26 +194,22 @@ while [ $index -lt ${envLength} ]; do EOF done -if [[ "${enablePV,,}" == "true" ]]; then +if [[ "${ENABLE_PV,,}" == "true" ]]; then cat <>$filePath # Optional volumes and mounts for the domain's pods. See also 'logHome'. volumes: - - name: ${wlsDomainUID}-pv-azurefile + - name: ${WLS_DOMAIN_UID}-pv-azurefile persistentVolumeClaim: - claimName: ${wlsDomainUID}-pvc-azurefile + claimName: ${WLS_DOMAIN_UID}-pvc-azurefile volumeMounts: - mountPath: /shared - name: ${wlsDomainUID}-pv-azurefile + name: ${WLS_DOMAIN_UID}-pv-azurefile EOF fi cat <>$filePath # The desired behavior for starting the domain's administration server. adminServer: - # The serverStartState legal values are "RUNNING" or "ADMIN" - # "RUNNING" means the listed server will be started up to "RUNNING" mode - # "ADMIN" means the listed server will be start up to "ADMIN" mode - serverStartState: "RUNNING" # Setup a Kubernetes node port for the administration server default channel #adminService: # channels: @@ -236,27 +219,9 @@ cat <>$filePath # The number of admin servers to start for unlisted clusters replicas: 1 - # The desired behavior for starting a specific cluster's member servers + # The name of each Cluster resource clusters: - - clusterName: cluster-1 - serverStartState: "RUNNING" - serverPod: - # Instructs Kubernetes scheduler to prefer nodes for new cluster members where there are not - # already members of the same cluster. - affinity: - podAntiAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 100 - podAffinityTerm: - labelSelector: - matchExpressions: - - key: "weblogic.clusterName" - operator: In - values: - - \$(CLUSTER_NAME) - topologyKey: "kubernetes.io/hostname" - # The number of managed servers to start for unlisted clusters - replicas: ${replicas} + - name: ${WLS_DOMAIN_UID}-cluster-1 # Change the restartVersion to force the introspector job to rerun # and apply any new model configuration, to also force a subsequent @@ -270,7 +235,7 @@ cat <>$filePath # Valid model domain types are 'WLS', 'JRF', and 'RestrictedJRF', default is 'WLS' domainType: "WLS" # All 'FromModel' domains require a runtimeEncryptionSecret with a 'password' field - runtimeEncryptionSecret: "${wlsDomainUID}-runtime-encryption-secret" + runtimeEncryptionSecret: "${WLS_DOMAIN_UID}-runtime-encryption-secret" EOF echo "set configmap..." @@ -295,4 +260,25 @@ EOF EOF index=$((index+1)) done -fi \ No newline at end of file +fi + +cat <>$filePath + +--- + +apiVersion: "weblogic.oracle/v1" +kind: Cluster +metadata: + name: ${WLS_DOMAIN_UID}-cluster-1 + # Update this with the namespace your domain will run in: + namespace: ${WLS_DOMAIN_UID}-ns + labels: + # Update this with the domainUID of your domain: + weblogic.domainUID: ${WLS_DOMAIN_UID} +spec: + # This must match a cluster name that is specified in the WebLogic configuration + clusterName: cluster-1 + # The number of managed servers to start for this cluster + replicas: 2 + +EOF \ No newline at end of file diff --git a/weblogic-azure-aks/src/main/arm/scripts/uploadAppGatewayTrutedRootCert.sh b/weblogic-azure-aks/src/main/arm/scripts/uploadAppGatewayTrutedRootCert.sh deleted file mode 100644 index 791377935..000000000 --- a/weblogic-azure-aks/src/main/arm/scripts/uploadAppGatewayTrutedRootCert.sh +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (c) 2021, Oracle Corporation and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# This script runs on Azure Container Instance with Alpine Linux that Azure Deployment script creates. - -# upload trusted root certificate to Azure Application Gateway -# $1: resource group name -# $2: Application Gateway name -# $3: one line based64 string of the certificate data - -# The value is used in setupNetworking.sh, please do not change it. -export appgwBackendSecretName='backend-tls' - -echo "output certificate data to backend-cert.cer" -echo "$3" | base64 -d >backend-cert.cer - -az network application-gateway root-cert create \ - --gateway-name $2 \ - --resource-group $1 \ - --name ${appgwBackendSecretName} \ - --cert-file backend-cert.cer - -if [ $? -ne 0 ]; then - echo "Failed to upload trusted root certificate to Application Gateway ${2}" - exit 1 -fi diff --git a/weblogic-azure-aks/src/main/arm/scripts/utility.sh b/weblogic-azure-aks/src/main/arm/scripts/utility.sh index 42b0cf113..68095d8da 100644 --- a/weblogic-azure-aks/src/main/arm/scripts/utility.sh +++ b/weblogic-azure-aks/src/main/arm/scripts/utility.sh @@ -1,4 +1,4 @@ -# Copyright (c) 2021, Oracle Corporation and/or its affiliates. +# Copyright (c) 2021, 2024 Oracle Corporation and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. # This script runs on Azure Container Instance with Alpine Linux that Azure Deployment script creates. @@ -18,34 +18,95 @@ function echo_stdout() { #Validate teminal status with $?, exit with exception if errors happen. function utility_validate_status() { - if [ $? == 1 ]; then - echo_stderr "$@" - echo_stderr "Errors happen, exit 1." - exit 1 - else - echo_stdout "$@" - fi + if [ $? == 1 ]; then + echo_stderr "$@" + echo_stderr "Errors happen, exit 1." + exit 1 + else + echo_stdout "$@" + fi } +function connect_aks(){ + az aks get-credentials \ + -n $1 \ + -g $2 \ + --overwrite-existing \ + --only-show-errors + + utility_validate_status "Finished connecting to AKS cluster." +} + +# JAVA_HOME=/usr/lib/jvm/java-11-openjdk function install_jdk() { - # Install Microsoft OpenJDK - apk --no-cache add openjdk11 --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community + local ready=false + local attempt=0 + while [[ "${ready}" == "false" && $attempt -le ${retryMaxAttempt} ]]; do + echo "Installing openjdk11 ${attempt}" + ready=true + # Install Microsoft OpenJDK + apk upgrade + apk add openjdk11 \ + --no-cache \ + -q --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community + + echo "java version" + java -version + if [ $? -eq 1 ]; then + ready=false + fi + + attempt=$((attempt + 1)) + sleep ${retryInterval} + done + + if [ ${attempt} -gt ${retryMaxAttempt} ]; then + echo_stderr "Failed to install openjdk11." + exit 1 + fi +} + +function install_docker() { + local ready=false + local attempt=0 + while [[ "${ready}" == "false" && $attempt -le ${retryMaxAttempt} ]]; do + echo "Installing docker ${attempt}" + ready=true + apk add docker --no-cache --quiet + docker --help + if [ $? -eq 1 ]; then + ready=false + fi + + attempt=$((attempt + 1)) + sleep ${retryInterval} + done - echo "java version" - java -version - if [ $? -eq 1 ]; then - echo_stderr "Failed to install open jdk 11." + if [ ${attempt} -gt ${retryMaxAttempt} ]; then + echo_stderr "Failed to install docker." exit 1 fi - # JAVA_HOME=/usr/lib/jvm/java-11-openjdk } function install_kubectl() { - # Install kubectl - az aks install-cli - echo "validate kubectl" - kubectl --help - if [ $? -eq 1 ]; then + local ready=false + local attempt=0 + while [[ "${ready}" == "false" && $attempt -le ${retryMaxAttempt} ]]; do + echo "Installing kubectl ${attempt}" + ready=true + # Install kubectl + az aks install-cli + echo "validate kubectl" + kubectl --help + if [ $? -eq 1 ]; then + ready=false + fi + + attempt=$((attempt + 1)) + sleep ${retryInterval} + done + + if [ ${attempt} -gt ${retryMaxAttempt} ]; then echo_stderr "Failed to install kubectl." exit 1 fi @@ -53,14 +114,14 @@ function install_kubectl() { function install_helm() { # Install Helm - browserURL=$(curl -m ${curlMaxTime} -s https://api.github.com/repos/helm/helm/releases/latest | + browserURL=$(curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -s https://api.github.com/repos/helm/helm/releases/latest | grep "browser_download_url.*linux-amd64.tar.gz.asc" | cut -d : -f 2,3 | tr -d \") helmLatestVersion=${browserURL#*download\/} helmLatestVersion=${helmLatestVersion%%\/helm*} helmPackageName=helm-${helmLatestVersion}-linux-amd64.tar.gz - curl -m ${curlMaxTime} -fL https://get.helm.sh/${helmPackageName} -o /tmp/${helmPackageName} + curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -fL https://get.helm.sh/${helmPackageName} -o /tmp/${helmPackageName} tar -zxvf /tmp/${helmPackageName} -C /tmp mv /tmp/linux-amd64/helm /usr/local/bin/helm echo "Helm version" @@ -141,6 +202,42 @@ function utility_upload_file_to_fileshare() { fi } +# +# Make sure all the applications are running +# Exit with error if there is inactive application. +# $1 - namespace of the domain +# $2 - ClusterIP service name of admin server +# $3 - domain user +# $4 - domain password +# $5 - path of python script which checks application status, the script will run on admin server pod. +function utility_validate_application_status() { + local wlsDomainNS=$1 + local wlsAdminSvcName=$2 + local wlsUser=$3 + local wlsShibboleth=$4 + local pyScriptPath=$5 + + local podName=$(kubectl -n ${wlsDomainNS} get pod -l weblogic.serverName=admin-server -o json | + jq '.items[0] | .metadata.name' | + tr -d "\"") + + # get non-ssl port + local adminTargetPort=$(kubectl get svc ${wlsAdminSvcName} -n ${wlsDomainNS} -o json | jq '.spec.ports[] | select(.name=="internal-t3") | .port') + local t3ChannelAddress="${podName}.${wlsDomainNS}" + + local targetFilePath=/tmp/checkApplicationStatus.py + echo "copy ${pyScriptPath} to ${targetFilePath}" + kubectl cp ${pyScriptPath} -n ${wlsDomainNS} ${podName}:${targetFilePath} + kubectl exec ${podName} -n ${wlsDomainNS} -c "weblogic-server" \ + -- bash -c "wlst.sh ${targetFilePath} -user ${wlsUser} -password ${wlsShibboleth} -t3ChannelAddress ${t3ChannelAddress} -t3ChannelPort ${adminTargetPort}" | + grep "Summary: all applications are active" + + if [ $? == 1 ]; then + echo_stderr "Failed to deploy application to WLS cluster. Please make sure the configurations are correct." + exit 1 + fi +} + # Call this function to make sure pods of a domain are running. # * Make sure the admin server pod is running # * Make sure all the managed server pods are running @@ -177,7 +274,7 @@ function utility_wait_for_pod_completed() { done if [ ${attempt} -gt ${checkPodStatusMaxAttemps} ]; then - echo_stderr "It takes too long to wait for all the pods are running, please refer to http://oracle.github.io/weblogic-kubernetes-operator/samples/simple/azure-kubernetes-service/#troubleshooting" + echo_stderr "It takes too long to wait for all the pods to reach running state, please refer to https://aka.ms/wls-aks-troubleshooting." exit 1 fi } @@ -252,7 +349,7 @@ function utility_wait_for_pod_restarted() { while [ ${updatedPodNum} -le ${appReplicas} ] && [ $attempt -le ${checkPodStatusMaxAttemps} ]; do echo "attempts ${attempt}" ret=$(kubectl get pods -n ${wlsDomainNS} -l weblogic.domainUID=${wlsDomainUID} -o json | - jq '.items[] | .metadata.creationTimestamp' | tr -d "\"") + jq '.items[] | select(all(.status.containerStatuses[]; .ready == true)) | .metadata.creationTimestamp' | tr -d "\"") counter=0 for item in $ret; do diff --git a/weblogic-azure-aks/src/main/arm/scripts/validateApplications.sh b/weblogic-azure-aks/src/main/arm/scripts/validateApplications.sh new file mode 100644 index 000000000..411603060 --- /dev/null +++ b/weblogic-azure-aks/src/main/arm/scripts/validateApplications.sh @@ -0,0 +1,30 @@ +# Copyright (c) 2021, 2024 Oracle Corporation and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +# This script runs on Azure Container Instance with Alpine Linux that Azure Deployment script creates. + +function validate_app() { + # make sure all the application are active, if not, fail the deployment. + local wlsDomainNS="${WLS_DOMAIN_UID}-ns" + local wlsAdminSvcName="${WLS_DOMAIN_UID}-admin-server" + scriptCheckAppStatus=$scriptDir/checkApplicationStatus.py + chmod ugo+x $scriptDir/checkApplicationStatus.py + utility_validate_application_status \ + ${wlsDomainNS} \ + ${wlsAdminSvcName} \ + ${WLS_DOMAIN_USER} \ + ${WLS_DOMAIN_SHIBBOLETH} \ + ${scriptCheckAppStatus} +} + +# Main script +export script="${BASH_SOURCE[0]}" +export scriptDir="$(cd "$(dirname "${script}")" && pwd)" + +source ${scriptDir}/common.sh +source ${scriptDir}/utility.sh + +install_kubectl + +connect_aks $AKS_NAME $AKS_RESOURCE_GROUP_NAME + +validate_app diff --git a/weblogic-azure-aks/src/main/bicep/mainTemplate.bicep b/weblogic-azure-aks/src/main/bicep/mainTemplate.bicep index b1e2608c0..7b55fa2be 100644 --- a/weblogic-azure-aks/src/main/bicep/mainTemplate.bicep +++ b/weblogic-azure-aks/src/main/bicep/mainTemplate.bicep @@ -1,5 +1,5 @@ /* -* Copyright (c) 2021, Oracle Corporation and/or its affiliates. +* Copyright (c) 2021, 2024, Oracle Corporation and/or its affiliates. * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. * * Terms: @@ -13,7 +13,10 @@ * * Build marketplace offer for test: * Replace the partner center pid in mainTemplate.bicep, then run the following command to generate the ARM package, and upload it to partner center. -* $ mvn -Pbicep -Ddev -Passembly clean install +* If using azure-javaee-iaas-parent less than 1.0.13, use: +* $ mvn -Pbicep -Passembly -Ddev clean install +* otherwise, use +* $ mvn -Pbicep-dev -Passembly clean install */ param _artifactsLocation string = deployment().properties.templateLink.uri @@ -26,18 +29,21 @@ param aciRetentionInDays int = 120 @description('Pricing tier: PerGB2018 or legacy tiers (Free, Standalone, PerNode, Standard or Premium) which are not available to all customers.') param aciWorkspaceSku string = 'pergb2018' param acrName string = 'acr-contoso' +param acrResourceGroupName string = 'acr-contoso-rg' @maxLength(12) @minLength(1) @description('The name for this node pool. Node pool must contain only lowercase letters and numbers. For Linux node pools the name cannot be longer than 12 characters.') -param aksAgentPoolName string = 'agentpool' +param aksAgentPoolName string = 'nodepool1' @maxValue(10000) @minValue(1) -@description('The number of nodes that should be created along with the cluster. You will be able to resize the cluster later.') +@description('Set the minimum node count for the cluster.') param aksAgentPoolNodeCount int = 3 +@maxValue(1000) +@minValue(3) +@description('Set the maximum node count for the cluster.') +param aksAgentPoolNodeMaxCount int = 5 @description('The size of the virtual machines that will form the nodes in the cluster. This cannot be changed after creating the cluster') -param aksAgentPoolVMSize string = 'Standard_DS2_v2' -@description('Prefix for cluster name. Only The name can contain only letters, numbers, underscores and hyphens. The name must start with letter or number.') -param aksClusterNamePrefix string = 'wlsonaks' +param vmSize string = 'Standard_DS2_v2' @description('Resource group name of an existing AKS cluster.') param aksClusterRGName string = 'aks-contoso-rg' @description('Name of an existing AKS cluster.') @@ -46,7 +52,6 @@ param aksClusterName string = 'aks-contoso' param aksVersion string = 'default' @allowed([ 'haveCert' - 'haveKeyVault' 'generateCert' ]) @description('Three scenarios we support for deploying app gateway') @@ -54,9 +59,11 @@ param appGatewayCertificateOption string = 'haveCert' @description('Public IP Name for the Application Gateway') param appGatewayPublicIPAddressName string = 'gwip' @description('The one-line, base64 string of the backend SSL root certificate data.') -param appGatewaySSLBackendRootCertData string = 'appgw-ssl-backend-data' +@secure() +param appGatewaySSLBackendRootCertData string = newGuid() @description('The one-line, base64 string of the SSL certificate data.') -param appGatewaySSLCertData string = 'appgw-ssl-data' +@secure() +param appGatewaySSLCertData string = newGuid() @secure() @description('The value of the password for the SSL Certificate') param appGatewaySSLCertPassword string = newGuid() @@ -64,10 +71,16 @@ param appGatewaySSLCertPassword string = newGuid() param appgwForAdminServer bool = true @description('Create Application Gateway ingress for remote console.') param appgwForRemoteConsole bool = true +@description('If true, configure Azure Application Gateway frontend IP with private IP.') +param appgwUsePrivateIP bool = false @description('Urls of Java EE application packages.') param appPackageUrls array = [] @description('The number of managed server to start.') param appReplicas int = 2 +@description('Scale up once average cpu utilization is larger then the input number ') +param averageCpuUtilization int = 60 +@description('Scale up once average memory utilization is larger then the input number ') +param averageMemoryUtilization int = 60 @description('true to create a new Azure Container Registry.') param createACR bool = false @description('true to create a new AKS cluster.') @@ -78,6 +91,8 @@ param createDNSZone bool = false 'oracle' 'postgresql' 'sqlserver' + 'mysql' + 'otherdb' ]) @description('One of the supported database types') param databaseType string = 'oracle' @@ -87,8 +102,19 @@ param databaseType string = 'oracle' ]) @description('createOrUpdate: create a new data source connection, or update an existing data source connection. delete: delete an existing data source connection') param dbConfigurationType string = 'createOrUpdate' +@description('Urls of datasource drivers, must be specified if database type is otherdb') +param dbDriverLibrariesUrls array = [] +@description('Datasource driver name, must be specified if database type is otherdb') +param dbDriverName string = 'org.contoso.Driver' +@description('Determines the transaction protocol (global transaction processing behavior) for the data source.') +param dbGlobalTranPro string = 'EmulateTwoPhaseCommit' +@description('Managed identity that has access to database') +param dbIdentity object = {} +@secure() @description('Password for Database') param dbPassword string = newGuid() +@description('The name of the database table to use when testing physical database connections. This name is required when you specify a Test Frequency and enable Test Reserved Connections.') +param dbTestTableName string = 'Null' @description('User id of Database') param dbUser string = 'contosoDbUser' @description('DNS prefix for ApplicationGateway') @@ -107,6 +133,8 @@ param dnszoneRGName string = 'dns-contoso-rg' param dsConnectionURL string = 'jdbc:postgresql://contoso.postgres.database.azure.com:5432/postgres' @description('true to set up Application Gateway ingress.') param enableAppGWIngress bool = false +@description('true to enable Horizontal Autoscaling.') +param enableAutoscaling bool = false @description('In addition to the CPU and memory metrics included in AKS by default, you can enable Container Insights for more comprehensive data on the overall performance and health of your cluster. Billing is based on data ingestion and retention settings.') param enableAzureMonitoring bool = false @description('true to create persistent volume using file share.') @@ -120,71 +148,32 @@ param enableDNSConfiguration bool = false param enableAdminT3Tunneling bool = false @description('Configure a custom channel in WebLogic cluster for the T3 protocol that enables HTTP tunneling') param enableClusterT3Tunneling bool = false -@description('An user assigned managed identity. Make sure the identity has permission to create/update/delete/list Azure resources.') -param identity object +@description('Enable passwordless datasource connection.') +param enablePswlessConnection bool = false +@allowed([ + 'cpu' + 'memory' +]) +param hpaScaleType string = 'cpu' +@description('Is the specified SSO account associated with an active Oracle support contract?') +param isSSOSupportEntitled bool = false @description('JNDI Name for JDBC Datasource') param jdbcDataSourceName string = 'jdbc/contoso' -@description('Existing Key Vault Name') -param keyVaultName string = 'kv-contoso' -@description('Resource group name in current subscription containing the KeyVault') -param keyVaultResourceGroup string = 'kv-contoso-rg' -@description('Price tier for Key Vault.') -param keyVaultSku string = 'Standard' -@description('The name of the secret in the specified KeyVault whose value is the SSL Root Certificate Data for Appliation Gateway backend TLS/SSL.') -param keyVaultSSLBackendRootCertDataSecretName string = 'kv-ssl-backend-data' -@description('The name of the secret in the specified KeyVault whose value is the SSL Certificate Data for Appliation Gateway frontend TLS/SSL.') -param keyVaultSSLCertDataSecretName string = 'kv-ssl-data' -@description('The name of the secret in the specified KeyVault whose value is the password for the SSL Certificate of Appliation Gateway frontend TLS/SSL') -param keyVaultSSLCertPasswordSecretName string = 'kv-ssl-psw' -param location string = 'eastus' +param location string @description('Object array to define Load Balancer service, each object must include service name, service target[admin-server or cluster-1], port.') param lbSvcValues array = [] @description('Name prefix of managed server.') param managedServerPrefix string = 'managed-server' +@description('To mitigate ARM-TTK error: Control Named vnetForApplicationGateway must output the newOrExisting property when hideExisting is false') +param newOrExistingVnetForApplicationGateway string = 'new' @secure() -@description('Password of Oracle SSO account.') -param ocrSSOPSW string +@description('Auth token of Oracle SSO account.') +param ocrSSOPSW string = newGuid() @description('User name of Oracle SSO account.') -param ocrSSOUser string -@secure() -@description('Base64 string of service principal. use the command to generate a testing string: az ad sp create-for-rbac --sdk-auth | base64 -w0') -param servicePrincipal string = newGuid() -@allowed([ - 'uploadConfig' - 'keyVaultStoredConfig' -]) -@description('Two scenarios to refer to WebLogic Server TLS/SSL certificates.') -param sslConfigurationAccessOption string = 'uploadConfig' -@description('Secret name in KeyVault containing Weblogic Custom Identity Keystore Data') -param sslKeyVaultCustomIdentityKeyStoreDataSecretName string = 'kv-wls-identity-data' -@description('Secret name in KeyVault containing Weblogic Custom Identity Keystore Passphrase') -param sslKeyVaultCustomIdentityKeyStorePassPhraseSecretName string = 'kv-wls-identity-psw' -@description('Weblogic Custom Identity Keystore type') -@allowed([ - 'JKS' - 'PKCS12' -]) -param sslKeyVaultCustomIdentityKeyStoreType string = 'PKCS12' -@description('Secret name in KeyVault containing Weblogic Custom Trust Store Data') -param sslKeyVaultCustomTrustKeyStoreDataSecretName string = 'kv-wls-trust-data' -@description('Secret name in KeyVault containing Weblogic Custom Trust Store Passphrase') -param sslKeyVaultCustomTrustKeyStorePassPhraseSecretName string = 'kv-wls-trust-psw' -@description('WWeblogic Custom Trust Store type') -@allowed([ - 'JKS' - 'PKCS12' -]) -param sslKeyVaultCustomTrustKeyStoreType string = 'PKCS12' -@description('Resource group containing Weblogic SSL certificates') -param sslKeyVaultName string = 'kv-wls-ssl-name' -@description('Secret name in KeyVault containing Weblogic Server private key alias') -param sslKeyVaultPrivateKeyAliasSecretName string = 'contoso' -@description('Secret name in KeyVault containing Weblogic Server private key passphrase') -param sslKeyVaultPrivateKeyPassPhraseSecretName string = 'kv-wls-ssl-alias' -@description('Keyvault name containing Weblogic SSL certificates') -param sslKeyVaultResourceGroup string = 'rg-kv-wls-ssl-name' +param ocrSSOUser string = 'null' @description('Custom Identity Store Data') -param sslUploadedCustomIdentityKeyStoreData string = 'null' +@secure() +param sslUploadedCustomIdentityKeyStoreData string = newGuid() @secure() @description('Custom Identity Store passphrase') param sslUploadedCustomIdentityKeyStorePassphrase string = newGuid() @@ -195,7 +184,8 @@ param sslUploadedCustomIdentityKeyStorePassphrase string = newGuid() ]) param sslUploadedCustomIdentityKeyStoreType string = 'PKCS12' @description('Custom Trust Store data') -param sslUploadedCustomTrustKeyStoreData string = 'null' +@secure() +param sslUploadedCustomTrustKeyStoreData string = newGuid() @secure() @description('Custom Trust Store passphrase') param sslUploadedCustomTrustKeyStorePassPhrase string = newGuid() @@ -206,18 +196,51 @@ param sslUploadedCustomTrustKeyStorePassPhrase string = newGuid() ]) param sslUploadedCustomTrustKeyStoreType string = 'PKCS12' @description('Alias of the private key') -param sslUploadedPrivateKeyAlias string = 'contoso' +@secure() +param sslUploadedPrivateKeyAlias string = newGuid() @secure() @description('Password of the private key') param sslUploadedPrivateKeyPassPhrase string = newGuid() +@description('${label.tagsLabel}') +param tagsByResource object = {} @description('Public port of the custom T3 channel in admin server') param t3ChannelAdminPort int = 7005 @description('Public port of the custom T3 channel in WebLoigc cluster') param t3ChannelClusterPort int = 8011 +@description('True to use latest supported Kubernetes version.') +param useLatestSupportedAksVersion bool = true +@description('True to enable HPA for auto scaling.') +param useHpa bool = true @description('True to set up internal load balancer service.') param useInternalLB bool = false -@description('ture to upload Java EE applications and deploy the applications to WebLogic domain.') param utcValue string = utcNow() +@description('User provided ACR for base image') +param userProvidedAcr string = 'null' +param userProvidedAcrRgName string = 'null' +@description('User provided base image path') +param userProvidedImagePath string = 'null' +@description('Use Oracle images or user provided patched images') +param useOracleImage bool = true +param validateApplications bool = false +@description('VNET for Application Gateway.') +param vnetForApplicationGateway object = { + name: 'wlsaks-app-gateway-vnet' + resourceGroup: resourceGroup().name + addressPrefixes: [ + '172.16.0.0/24' + ] + addressPrefix: '172.16.0.0/24' + newOrExisting: 'new' + subnets: { + gatewaySubnet: { + name: 'wlsaks-gateway-subnet' + addressPrefix: '172.16.0.0/24' + startAddress: '172.16.0.4' + } + } +} +@description('To mitigate ARM-TTK error: Control Named vnetForApplicationGateway must output the resourceGroup property when hideExisting is false') +param vnetRGNameForApplicationGateway string = 'vnet-contoso-rg-name' @secure() @description('Password for model WebLogic Deploy Tooling runtime encrytion.') param wdtRuntimePassword string @@ -239,41 +262,64 @@ param wlsPassword string @description('User name for WebLogic Administrator.') param wlsUserName string = 'weblogic' -var const_appGatewaySSLCertOptionHaveCert = 'haveCert' -var const_appGatewaySSLCertOptionHaveKeyVault = 'haveKeyVault' -var const_azureSubjectName = '${format('{0}.{1}.{2}', name_domainLabelforApplicationGateway, location, 'cloudapp.azure.com')}' -var const_hasTags = contains(resourceGroup(), 'tags') -// If there is not tag 'wlsKeyVault' and key vault is created for the following usage: -// * upload custom TLS/SSL certificates for WLS trust and identity. -// * upload custom certificate for gateway frontend TLS/SSL. -// * generate selfsigned certificate for gateway frontend TLS/SSL. -var const_bCreateNewKeyVault = (!const_hasTags || !contains(resourceGroup().tags, name_tagNameForKeyVault) || empty(resourceGroup().tags.wlsKeyVault)) && ((enableCustomSSL && sslConfigurationAccessOption != const_wlsSSLCertOptionKeyVault) || (enableAppGWIngress && (appGatewayCertificateOption != const_appGatewaySSLCertOptionHaveKeyVault))) -var const_bCreateStorageAccount = (createAKSCluster || !const_hasStorageAccount) && const_enablePV +// To mitigate arm-ttk error: Type Mismatch: Parameter in nested template is defined as string, but the parent template defines it as bool. +var _enableCustomSSL = enableCustomSSL +var _enableAppGWIngress = enableAppGWIngress +// We can streamline the following code with a user-defined function, but it is not supported in Partner Center. +// For status, see https://dev.azure.com/edburns-msft/Open%20Standard%20Enterprise%20Java%20(Java%20EE)%20on%20Azure/_workitems/edit/6219 +var _objTagsByResource = { + '${identifier.accounts}': contains(tagsByResource, '${identifier.accounts}') ? tagsByResource['${identifier.accounts}'] : json('{}') + '${identifier.managedClusters}': contains(tagsByResource, '${identifier.managedClusters}') ? tagsByResource['${identifier.managedClusters}'] : json('{}') + '${identifier.applicationGateways}': contains(tagsByResource, '${identifier.applicationGateways}') ? tagsByResource['${identifier.applicationGateways}'] : json('{}') + '${identifier.registries}': contains(tagsByResource, '${identifier.registries}') ? tagsByResource['${identifier.registries}'] : json('{}') + '${identifier.virtualMachines}': contains(tagsByResource, '${identifier.virtualMachines}') ? tagsByResource['${identifier.virtualMachines}'] : json('{}') + '${identifier.virtualMachinesExtensions}': contains(tagsByResource, '${identifier.virtualMachinesExtensions}') ? tagsByResource['${identifier.virtualMachinesExtensions}'] : json('{}') + '${identifier.virtualNetworks}': contains(tagsByResource, '${identifier.virtualNetworks}') ? tagsByResource['${identifier.virtualNetworks}'] : json('{}') + '${identifier.networkInterfaces}': contains(tagsByResource, '${identifier.networkInterfaces}') ? tagsByResource['${identifier.networkInterfaces}'] : json('{}') + '${identifier.networkSecurityGroups}': contains(tagsByResource, '${identifier.networkSecurityGroups}') ? tagsByResource['${identifier.networkSecurityGroups}'] : json('{}') + '${identifier.publicIPAddresses}': contains(tagsByResource, '${identifier.publicIPAddresses}') ? tagsByResource['${identifier.publicIPAddresses}'] : json('{}') + '${identifier.storageAccounts}': contains(tagsByResource, '${identifier.storageAccounts}') ? tagsByResource['${identifier.storageAccounts}'] : json('{}') + '${identifier.vaults}': contains(tagsByResource, '${identifier.vaults}') ? tagsByResource['${identifier.vaults}'] : json('{}') + '${identifier.userAssignedIdentities}': contains(tagsByResource, '${identifier.userAssignedIdentities}') ? tagsByResource['${identifier.userAssignedIdentities}'] : json('{}') + '${identifier.dnszones}': contains(tagsByResource, '${identifier.dnszones}') ? tagsByResource['${identifier.dnszones}'] : json('{}') + '${identifier.workspaces}': contains(tagsByResource, '${identifier.workspaces}') ? tagsByResource['${identifier.workspaces}'] : json('{}') + '${identifier.deploymentScripts}': contains(tagsByResource, '${identifier.deploymentScripts}') ? tagsByResource['${identifier.deploymentScripts}'] : json('{}') +} +var const_aksName = createAKSCluster ? 'wlsonaks${const_globalResourceNameSuffix}' : aksClusterName +var const_appGatewaySSLCertOptionGenerateCert = 'generateCert' +var const_appGatewayPublicIPAddressName = format('{0}-{1}', appGatewayPublicIPAddressName, const_globalResourceNameSuffix) +var const_acrName = (createACR) ? 'acrwlsaks${const_globalResourceNameSuffix}' : acrName +var const_azcliVersion = '2.53.0' +var const_azureSubjectName = format('{0}.{1}.{2}', name_domainLabelforApplicationGateway, location, 'cloudapp.azure.com') +var const_bValidateApplications= validateApplications && (length(appPackageUrls) > 0) +var const_cpuPlatform = (contains(vmSize, 'p') ? 'arm64' : 'amd64') +var const_createNewAcr = useOracleImage && createACR var const_defaultKeystoreType = 'PKCS12' var const_enableNetworking = (length(lbSvcValues) > 0) || enableAppGWIngress var const_enablePV = enableCustomSSL || enableAzureFileShare -var const_hasStorageAccount = !createAKSCluster && reference('query-existing-storage-account').outputs.storageAccount.value != 'null' -var const_identityKeyStoreType = (sslConfigurationAccessOption == const_wlsSSLCertOptionKeyVault) ? sslKeyVaultCustomIdentityKeyStoreType : sslUploadedCustomIdentityKeyStoreType -var const_keyvaultNameFromTag = const_hasTags && contains(resourceGroup().tags, name_tagNameForKeyVault) ? resourceGroup().tags.wlsKeyVault : '' -var const_trustKeyStoreType = (sslConfigurationAccessOption == const_wlsSSLCertOptionKeyVault) ? sslKeyVaultCustomTrustKeyStoreType : sslUploadedCustomTrustKeyStoreType +var const_fileShareName = 'weblogic-${const_globalResourceNameSuffix}' +var const_globalResourceNameSuffix = '${uniqueString(utcValue)}' +var const_nsgName = 'wls-aks-nsg-${const_globalResourceNameSuffix}' +var const_showAdminConsoleExUrl = (length(lbSvcValues) > 0) || (enableAppGWIngress && appgwForAdminServer) +var const_showRemoteAdminConsoleExUrl = ((length(lbSvcValues) > 0) || (enableAppGWIngress && appgwForRemoteConsole)) && !enableCustomSSL +var const_showRemoteAdminConsoleSecuredExUrl = ((length(lbSvcValues) > 0) || (enableAppGWIngress && appgwForRemoteConsole)) && enableCustomSSL +var const_wlsClusterName = 'cluster-1' var const_wlsJavaOptions = wlsJavaOption == '' ? 'null' : wlsJavaOption -var const_wlsSSLCertOptionKeyVault = 'keyVaultStoredConfig' +var name_appgwFrontendSSLCertName = 'appGatewaySslCert' +var name_appgwBackendRootCertName = 'appGatewayTrustedRootCert' var name_defaultPidDeployment = 'pid' -var name_dnsNameforApplicationGateway = '${concat(dnsNameforApplicationGateway, take(utcValue, 6))}' -var name_domainLabelforApplicationGateway = '${take(concat(name_dnsNameforApplicationGateway, '-', toLower(name_rgNameWithoutSpecialCharacter), '-', toLower(wlsDomainName)), 63)}' -var name_identityKeyStoreDataSecret = (sslConfigurationAccessOption == const_wlsSSLCertOptionKeyVault) ? sslKeyVaultCustomIdentityKeyStoreDataSecretName : 'myIdentityKeyStoreData' -var name_identityKeyStorePswSecret = (sslConfigurationAccessOption == const_wlsSSLCertOptionKeyVault) ? sslKeyVaultCustomIdentityKeyStorePassPhraseSecretName : 'myIdentityKeyStorePsw' -var name_keyVaultName = empty(const_keyvaultNameFromTag) ? '${take(concat('wls-kv', uniqueString(utcValue)), 24)}' : resourceGroup().tags.wlsKeyVault -var name_privateKeyAliasSecret = (sslConfigurationAccessOption == const_wlsSSLCertOptionKeyVault) ? sslKeyVaultPrivateKeyAliasSecretName : 'privateKeyAlias' -var name_privateKeyPswSecret = (sslConfigurationAccessOption == const_wlsSSLCertOptionKeyVault) ? sslKeyVaultPrivateKeyPassPhraseSecretName : 'privateKeyPsw' -var name_rgNameWithoutSpecialCharacter= replace(replace(replace(replace(resourceGroup().name, '.', ''), '(', ''), ')', ''), '_', '') // remove . () _ from resource group name -var name_rgKeyvaultForWLSSSL = (sslConfigurationAccessOption == const_wlsSSLCertOptionKeyVault) ? sslKeyVaultResourceGroup : resourceGroup().name -var name_storageAccountName = const_hasStorageAccount ? reference('query-existing-storage-account').outputs.storageAccount.value : 'wls${uniqueString(utcValue)}' -var name_tagNameForKeyVault = 'wlsKeyVault' -var name_tagNameForStorageAccount = 'wlsStorageAccount' -var name_trustKeyStoreDataSecret = (sslConfigurationAccessOption == const_wlsSSLCertOptionKeyVault) ? sslKeyVaultCustomTrustKeyStoreDataSecretName : 'myTrustKeyStoreData' -var name_trustKeyStorePswSecret = (sslConfigurationAccessOption == const_wlsSSLCertOptionKeyVault) ? sslKeyVaultCustomTrustKeyStorePassPhraseSecretName : 'myTrustKeyStorePsw' -var ref_wlsDomainDeployment = reference(resourceId('Microsoft.Resources/deployments', (enableCustomSSL) ? 'setup-wls-cluster-with-custom-ssl-enabled' : 'setup-wls-cluster')) +var name_dnsNameforApplicationGateway = '${dnsNameforApplicationGateway}${const_globalResourceNameSuffix}' +var name_domainLabelforApplicationGateway = take('${name_dnsNameforApplicationGateway}-${toLower(name_rgNameWithoutSpecialCharacter)}-${toLower(wlsDomainName)}', 63) +var name_rgNameWithoutSpecialCharacter = replace(replace(replace(replace(resourceGroup().name, '.', ''), '(', ''), ')', ''), '_', '') // remove . () _ from resource group name +var name_storageAccountName = 'wls${const_globalResourceNameSuffix}' +var ref_wlsDomainDeployment = _enableCustomSSL ? wlsDomainWithCustomSSLDeployment : wlsDomainDeployment +var obj_uamiForDeploymentScript = { + type: 'UserAssigned' + userAssignedIdentities: { + '${uamiDeployment.outputs.uamiIdForDeploymentScript}': {} + } +} + /* * Beginning of the offer deployment */ @@ -287,44 +333,129 @@ module partnerCenterPid './modules/_pids/_empty.bicep' = { name: 'pid-a1775ed4-512c-4cfa-9e68-f0b09b36de90-partnercenter' } -module wlsSSLCertSecretsDeployment 'modules/_azure-resoruces/_keyvault/_keyvaultForWLSSSLCert.bicep' = if (enableCustomSSL && sslConfigurationAccessOption != const_wlsSSLCertOptionKeyVault) { - name: 'upload-wls-ssl-cert-to-keyvault' +module uamiDeployment 'modules/_globalUamiAndRoles.bicep' = { + name: 'uami-deployment' params: { - keyVaultName: name_keyVaultName - sku: keyVaultSku - wlsIdentityKeyStoreData: sslUploadedCustomIdentityKeyStoreData - wlsIdentityKeyStoreDataSecretName: name_identityKeyStoreDataSecret - wlsIdentityKeyStorePassphrase: sslUploadedCustomIdentityKeyStorePassphrase - wlsIdentityKeyStorePassphraseSecretName: name_identityKeyStorePswSecret - wlsPrivateKeyAlias: sslUploadedPrivateKeyAlias - wlsPrivateKeyAliasSecretName: name_privateKeyAliasSecret - wlsPrivateKeyPassPhrase: sslUploadedPrivateKeyPassPhrase - wlsPrivateKeyPassPhraseSecretName: name_privateKeyPswSecret - wlsTrustKeyStoreData: sslUploadedCustomTrustKeyStoreData - wlsTrustKeyStoreDataSecretName: name_trustKeyStoreDataSecret - wlsTrustKeyStorePassPhrase: sslUploadedCustomTrustKeyStorePassPhrase - wlsTrustKeyStorePassPhraseSecretName: name_trustKeyStorePswSecret + _globalResourceNameSuffix: const_globalResourceNameSuffix + location: location + tagsByResource: _objTagsByResource + } +} + +/* +* Deploy ACR +*/ +module preAzureResourceDeployment './modules/_preDeployedAzureResources.bicep' = { + name: 'prerequisite-resources-deployment' + params: { + acrName: const_acrName + acrResourceGroupName: acrResourceGroupName + createNewAcr: const_createNewAcr + location: location + tagsByResource: _objTagsByResource + } +} + +module validateInputs 'modules/_deployment-scripts/_ds-validate-parameters.bicep' = { + name: 'validate-parameters-and-fail-fast' + params: { + _globalResourceNameSuffix: const_globalResourceNameSuffix + acrName: preAzureResourceDeployment.outputs.acrName + acrResourceGroupName: preAzureResourceDeployment.outputs.acrResourceGroupName + aksAgentPoolNodeCount: aksAgentPoolNodeCount + aksAgentPoolVMSize: vmSize + aksClusterRGName: aksClusterRGName + aksClusterName: aksClusterName + aksVersion: aksVersion + appGatewayCertificateOption: appGatewayCertificateOption + appGatewaySSLCertData: appGatewaySSLCertData + appGatewaySSLCertPassword: appGatewaySSLCertPassword + appReplicas: appReplicas + azCliVersion: const_azcliVersion + createAKSCluster: createAKSCluster + createDNSZone: createDNSZone + dnszoneName: dnszoneName + dnszoneRGName: dnszoneRGName + enableAppGWIngress: enableAppGWIngress + enableCustomSSL: enableCustomSSL + enableDNSConfiguration: enableDNSConfiguration + identity: obj_uamiForDeploymentScript + isSSOSupportEntitled: isSSOSupportEntitled + location: location + ocrSSOPSW: ocrSSOPSW + ocrSSOUser: ocrSSOUser + sslUploadedCustomIdentityKeyStoreData: sslUploadedCustomIdentityKeyStoreData + sslUploadedCustomIdentityKeyStorePassphrase: sslUploadedCustomIdentityKeyStorePassphrase + sslUploadedCustomIdentityKeyStoreType: sslUploadedCustomIdentityKeyStoreType + sslUploadedCustomTrustKeyStoreData: sslUploadedCustomTrustKeyStoreData + sslUploadedCustomTrustKeyStorePassPhrase: sslUploadedCustomTrustKeyStorePassPhrase + sslUploadedCustomTrustKeyStoreType: sslUploadedCustomTrustKeyStoreType + sslUploadedPrivateKeyAlias: sslUploadedPrivateKeyAlias + sslUploadedPrivateKeyPassPhrase: sslUploadedPrivateKeyPassPhrase + tagsByResource: _objTagsByResource + useAksWellTestedVersion: useLatestSupportedAksVersion + userProvidedAcr: userProvidedAcr // used in user provided images + userProvidedAcrRgName: userProvidedAcrRgName + userProvidedImagePath: userProvidedImagePath + useOracleImage: useOracleImage + vnetForApplicationGateway: vnetForApplicationGateway + wlsImageTag: wlsImageTag } dependsOn: [ pids + preAzureResourceDeployment + uamiDeployment ] } -// get key vault object in a resource group -resource sslKeyvault 'Microsoft.KeyVault/vaults@2019-09-01' existing = if (enableCustomSSL) { - name: (sslConfigurationAccessOption == const_wlsSSLCertOptionKeyVault) ? sslKeyVaultName : name_keyVaultName - scope: resourceGroup(name_rgKeyvaultForWLSSSL) +module autoGeneratedSSLCert './modules/_azure-resoruces/_autoGeneratedPfxCertInKeyVault.bicep' = if (enableAppGWIngress && appGatewayCertificateOption == const_appGatewaySSLCertOptionGenerateCert) { + name: 'auto-generated-ssl-cert-for-app-gateway' + params: { + _globalResourceNameSuffix: const_globalResourceNameSuffix + identity: obj_uamiForDeploymentScript + keyVaultName: 'wlskv${const_globalResourceNameSuffix}' + location: location + secretName: name_appgwFrontendSSLCertName + subjectName: format('CN={0}', enableDNSConfiguration ? format('{0}.{1}', dnsNameforApplicationGateway, dnszoneName) : const_azureSubjectName) + tagsByResource: _objTagsByResource + } + dependsOn: [ + uamiDeployment + ] } -// If updating an existing aks cluster, query the storage account that is being used. -// Return "null" is no storage account is applied. -module queryStorageAccount 'modules/_deployment-scripts/_ds-query-storage-account.bicep' = if (!createAKSCluster) { - name: 'query-existing-storage-account' +// To void space overlap with AKS VNet, must deploy the Applciation Gateway VNet before AKS deployment. +module appgatewayDeployment 'modules/_appGateway.bicep' = if (enableAppGWIngress) { + name: 'application-gateway-deployment' params: { - aksClusterName: aksClusterName - aksClusterRGName: aksClusterRGName - identity: identity + _pidAppgwEnd: pids.outputs.appgwEnd == '' ? name_defaultPidDeployment : pids.outputs.appgwEnd + _pidAppgwStart: pids.outputs.appgwStart == '' ? name_defaultPidDeployment : pids.outputs.appgwStart + _pidAppgwWithCustomCert: pids.outputs.customCertForAppgw == '' ? name_defaultPidDeployment : pids.outputs.customCertForAppgw + appgwCertificateOption: appGatewayCertificateOption + appgwName: 'appgw${const_globalResourceNameSuffix}' + appgwPublicIPAddressName: const_appGatewayPublicIPAddressName + appgwSSLBackendRootCertData: appGatewaySSLBackendRootCertData + appgwUsePrivateIP: appgwUsePrivateIP + azCliVersion: const_azcliVersion + autoGeneratedSSLCertKeyVaultName: appGatewayCertificateOption == const_appGatewaySSLCertOptionGenerateCert ? autoGeneratedSSLCert.outputs.keyVaultName : '' + autoGeneratedSSLCertSecretName: appGatewayCertificateOption == const_appGatewaySSLCertOptionGenerateCert ? autoGeneratedSSLCert.outputs.secretName : '' + dnsNameforApplicationGateway: name_domainLabelforApplicationGateway + enableCustomSSL: enableCustomSSL + identity: obj_uamiForDeploymentScript + nsgName: const_nsgName + location: location + newOrExistingVnetForApplicationGateway: newOrExistingVnetForApplicationGateway + sslCertData: appGatewaySSLCertData + sslCertificateDeploymentName: name_appgwFrontendSSLCertName + sslCertPswData: appGatewaySSLCertPassword + trustedRootCertificateDeploymentName: name_appgwBackendRootCertName + vnetForApplicationGateway: vnetForApplicationGateway + vnetRGNameForApplicationGateway: vnetRGNameForApplicationGateway + tagsByResource: _objTagsByResource } + dependsOn: [ + autoGeneratedSSLCert + ] } module wlsDomainDeployment 'modules/setupWebLogicCluster.bicep' = if (!enableCustomSSL) { @@ -332,30 +463,39 @@ module wlsDomainDeployment 'modules/setupWebLogicCluster.bicep' = if (!enableCus params: { _artifactsLocation: _artifactsLocation _artifactsLocationSasToken: _artifactsLocationSasToken + _globalResourceNameSuffix: const_globalResourceNameSuffix _pidEnd: pids.outputs.wlsAKSEnd == '' ? name_defaultPidDeployment : pids.outputs.wlsAKSEnd + _pidSSLEnd: pids.outputs.sslEnd == '' ? name_defaultPidDeployment : pids.outputs.sslEnd + _pidSSLStart: pids.outputs.sslStart == '' ? name_defaultPidDeployment : pids.outputs.sslStart _pidStart: pids.outputs.wlsAKSStart == '' ? name_defaultPidDeployment : pids.outputs.wlsAKSStart aciResourcePermissions: aciResourcePermissions aciRetentionInDays: aciRetentionInDays aciWorkspaceSku: aciWorkspaceSku - acrName: acrName + acrName: preAzureResourceDeployment.outputs.acrName + acrResourceGroupName: preAzureResourceDeployment.outputs.acrResourceGroupName aksAgentPoolName: aksAgentPoolName aksAgentPoolNodeCount: aksAgentPoolNodeCount - aksAgentPoolVMSize: aksAgentPoolVMSize - aksClusterNamePrefix: aksClusterNamePrefix + aksAgentPoolNodeMaxCount: aksAgentPoolNodeMaxCount + vmSize: vmSize aksClusterRGName: aksClusterRGName - aksClusterName: aksClusterName - aksVersion: aksVersion + aksClusterName: const_aksName + aksVersion: validateInputs.outputs.aksVersion appPackageUrls: appPackageUrls appReplicas: appReplicas - createACR: createACR + azCliVersion: const_azcliVersion + cpuPlatform: const_cpuPlatform createAKSCluster: createAKSCluster - createStorageAccount: const_bCreateStorageAccount + databaseType: databaseType + dbDriverLibrariesUrls: dbDriverLibrariesUrls enableAzureMonitoring: enableAzureMonitoring enableCustomSSL: enableCustomSSL enableAdminT3Tunneling: enableAdminT3Tunneling enableClusterT3Tunneling: enableClusterT3Tunneling + enablePswlessConnection: enablePswlessConnection enablePV: const_enablePV - identity: identity + fileShareName: const_fileShareName + identity: obj_uamiForDeploymentScript + isSSOSupportEntitled: isSSOSupportEntitled location: location managedServerPrefix: managedServerPrefix ocrSSOPSW: ocrSSOPSW @@ -363,7 +503,12 @@ module wlsDomainDeployment 'modules/setupWebLogicCluster.bicep' = if (!enableCus storageAccountName: name_storageAccountName t3ChannelAdminPort: t3ChannelAdminPort t3ChannelClusterPort: t3ChannelClusterPort + tagsByResource: _objTagsByResource wdtRuntimePassword: wdtRuntimePassword + userProvidedAcr: userProvidedAcr + userProvidedAcrRgName: userProvidedAcrRgName + userProvidedImagePath: userProvidedImagePath + useOracleImage: useOracleImage wlsClusterSize: wlsClusterSize wlsCPU: wlsCPU wlsDomainName: wlsDomainName @@ -383,8 +528,7 @@ module wlsDomainDeployment 'modules/setupWebLogicCluster.bicep' = if (!enableCus wlsUserName: wlsUserName } dependsOn: [ - pids - queryStorageAccount + validateInputs ] } @@ -393,30 +537,37 @@ module wlsDomainWithCustomSSLDeployment 'modules/setupWebLogicCluster.bicep' = i params: { _artifactsLocation: _artifactsLocation _artifactsLocationSasToken: _artifactsLocationSasToken + _globalResourceNameSuffix: const_globalResourceNameSuffix _pidEnd: pids.outputs.wlsAKSEnd == '' ? name_defaultPidDeployment : pids.outputs.wlsAKSEnd _pidStart: pids.outputs.wlsAKSStart == '' ? name_defaultPidDeployment : pids.outputs.wlsAKSStart aciResourcePermissions: aciResourcePermissions aciRetentionInDays: aciRetentionInDays aciWorkspaceSku: aciWorkspaceSku - acrName: acrName + acrName: preAzureResourceDeployment.outputs.acrName + acrResourceGroupName: preAzureResourceDeployment.outputs.acrResourceGroupName aksAgentPoolName: aksAgentPoolName aksAgentPoolNodeCount: aksAgentPoolNodeCount - aksAgentPoolVMSize: aksAgentPoolVMSize - aksClusterNamePrefix: aksClusterNamePrefix + aksAgentPoolNodeMaxCount: aksAgentPoolNodeMaxCount + vmSize: vmSize aksClusterRGName: aksClusterRGName - aksClusterName: aksClusterName - aksVersion: aksVersion + aksClusterName: const_aksName + aksVersion: validateInputs.outputs.aksVersion appPackageUrls: appPackageUrls appReplicas: appReplicas - createACR: createACR + azCliVersion: const_azcliVersion + cpuPlatform: const_cpuPlatform createAKSCluster: createAKSCluster - createStorageAccount: const_bCreateStorageAccount + databaseType: databaseType + dbDriverLibrariesUrls: dbDriverLibrariesUrls enableAzureMonitoring: enableAzureMonitoring enableCustomSSL: enableCustomSSL enableAdminT3Tunneling: enableAdminT3Tunneling enableClusterT3Tunneling: enableClusterT3Tunneling + enablePswlessConnection: enablePswlessConnection enablePV: const_enablePV - identity: identity + fileShareName: const_fileShareName + identity: obj_uamiForDeploymentScript + isSSOSupportEntitled: isSSOSupportEntitled location: location managedServerPrefix: managedServerPrefix ocrSSOPSW: ocrSSOPSW @@ -424,63 +575,32 @@ module wlsDomainWithCustomSSLDeployment 'modules/setupWebLogicCluster.bicep' = i storageAccountName: name_storageAccountName t3ChannelAdminPort: t3ChannelAdminPort t3ChannelClusterPort: t3ChannelClusterPort + userProvidedAcr: userProvidedAcr + userProvidedAcrRgName: userProvidedAcrRgName + userProvidedImagePath: userProvidedImagePath + useOracleImage: useOracleImage + tagsByResource: _objTagsByResource wdtRuntimePassword: wdtRuntimePassword wlsClusterSize: wlsClusterSize wlsCPU: wlsCPU wlsDomainName: wlsDomainName wlsDomainUID: wlsDomainUID - wlsIdentityKeyStoreData: sslKeyvault.getSecret(name_identityKeyStoreDataSecret) - wlsIdentityKeyStorePassphrase: sslKeyvault.getSecret(name_identityKeyStorePswSecret) - wlsIdentityKeyStoreType: const_identityKeyStoreType + wlsIdentityKeyStoreData: sslUploadedCustomIdentityKeyStoreData + wlsIdentityKeyStorePassphrase: sslUploadedCustomIdentityKeyStorePassphrase + wlsIdentityKeyStoreType: sslUploadedCustomIdentityKeyStoreType wlsImageTag: wlsImageTag wlsJavaOption: const_wlsJavaOptions wlsMemory: wlsMemory wlsPassword: wlsPassword - wlsPrivateKeyAlias: sslKeyvault.getSecret(name_privateKeyAliasSecret) - wlsPrivateKeyPassPhrase: sslKeyvault.getSecret(name_privateKeyPswSecret) - wlsTrustKeyStoreData: sslKeyvault.getSecret(name_trustKeyStoreDataSecret) - wlsTrustKeyStorePassPhrase: sslKeyvault.getSecret(name_trustKeyStorePswSecret) - wlsTrustKeyStoreType: const_trustKeyStoreType + wlsPrivateKeyAlias: sslUploadedPrivateKeyAlias + wlsPrivateKeyPassPhrase: sslUploadedPrivateKeyPassPhrase + wlsTrustKeyStoreData: sslUploadedCustomTrustKeyStoreData + wlsTrustKeyStorePassPhrase: sslUploadedCustomTrustKeyStorePassPhrase + wlsTrustKeyStoreType: sslUploadedCustomTrustKeyStoreType wlsUserName: wlsUserName } dependsOn: [ - wlsSSLCertSecretsDeployment - queryStorageAccount - ] -} - -module appgwSecretDeployment 'modules/_azure-resoruces/_keyvaultForGateway.bicep' = if (enableAppGWIngress && (appGatewayCertificateOption != const_appGatewaySSLCertOptionHaveKeyVault)) { - name: 'appgateway-certificates-secrets-deployment' - params: { - backendCertificateDataValue: appGatewaySSLBackendRootCertData - certificateDataValue: appGatewaySSLCertData - certificatePasswordValue: appGatewaySSLCertPassword - enableCustomSSL: enableCustomSSL - identity: identity - sku: keyVaultSku - subjectName: format('CN={0}', enableDNSConfiguration ? format('{0}.{1}', dnsNameforApplicationGateway, dnszoneName) : const_azureSubjectName) - useExistingAppGatewaySSLCertificate: (appGatewayCertificateOption == const_appGatewaySSLCertOptionHaveCert) ? true : false - keyVaultName: name_keyVaultName - } - dependsOn: [ - wlsDomainDeployment - wlsDomainWithCustomSSLDeployment - ] -} - -/* - * Update tags to save key vault name and storage account name that are used for current configuration -*/ -resource applyTags 'Microsoft.Resources/tags@2021-04-01' = { - name: 'default' - properties: { - tags: { - '${name_tagNameForKeyVault}': const_bCreateNewKeyVault ? name_keyVaultName : const_keyvaultNameFromTag - '${name_tagNameForStorageAccount}': (const_bCreateStorageAccount || const_hasStorageAccount) ? name_storageAccountName : '' - } - } - dependsOn: [ - appgwSecretDeployment + validateInputs ] } @@ -489,18 +609,23 @@ module networkingDeployment 'modules/networking.bicep' = if (const_enableNetwork params: { _artifactsLocation: _artifactsLocation _artifactsLocationSasToken: _artifactsLocationSasToken + _globalResourceNameSuffix: const_globalResourceNameSuffix _pidNetworkingEnd: pids.outputs.networkingEnd == '' ? name_defaultPidDeployment : pids.outputs.networkingEnd _pidNetworkingStart: pids.outputs.networkingStart == '' ? name_defaultPidDeployment : pids.outputs.networkingStart - _pidAppgwEnd: pids.outputs.appgwEnd == '' ? name_defaultPidDeployment : pids.outputs.appgwEnd - _pidAppgwStart: pids.outputs.appgwStart == '' ? name_defaultPidDeployment : pids.outputs.appgwStart - aksClusterRGName: ref_wlsDomainDeployment.outputs.aksClusterRGName.value - aksClusterName: ref_wlsDomainDeployment.outputs.aksClusterName.value - appGatewayCertificateOption: appGatewayCertificateOption - appGatewayPublicIPAddressName: appGatewayPublicIPAddressName + aksClusterRGName: ref_wlsDomainDeployment.outputs.aksClusterRGName + aksClusterName: ref_wlsDomainDeployment.outputs.aksClusterName + appGatewayName: _enableAppGWIngress ? appgatewayDeployment.outputs.appGatewayName : '' + appGatewayAlias: _enableAppGWIngress ? appgatewayDeployment.outputs.appGatewayAlias : '' + appGatewaySecuredURL: _enableAppGWIngress ? appgatewayDeployment.outputs.appGatewaySecuredURL : '' + appGatewayURL: _enableAppGWIngress ? appgatewayDeployment.outputs.appGatewayURL : '' + appGatewaySslCert: name_appgwFrontendSSLCertName + appGatewayTrustedRootCert: name_appgwBackendRootCertName + appgwUsePrivateIP: appgwUsePrivateIP appgwForAdminServer: appgwForAdminServer appgwForRemoteConsole: appgwForRemoteConsole + azCliVersion: const_azcliVersion + createAKSCluster: createAKSCluster createDNSZone: createDNSZone - dnsNameforApplicationGateway: name_domainLabelforApplicationGateway dnszoneAdminConsoleLabel: dnszoneAdminConsoleLabel dnszoneAdminT3ChannelLabel: dnszoneAdminT3ChannelLabel dnszoneClusterLabel: dnszoneClusterLabel @@ -511,40 +636,46 @@ module networkingDeployment 'modules/networking.bicep' = if (const_enableNetwork enableCookieBasedAffinity: enableCookieBasedAffinity enableCustomSSL: enableCustomSSL enableDNSConfiguration: enableDNSConfiguration - identity: identity - keyVaultName: (!enableAppGWIngress || (appGatewayCertificateOption == const_appGatewaySSLCertOptionHaveKeyVault)) ? keyVaultName : appgwSecretDeployment.outputs.keyVaultName - keyVaultResourceGroup: (!enableAppGWIngress || (appGatewayCertificateOption == const_appGatewaySSLCertOptionHaveKeyVault)) ? keyVaultResourceGroup : resourceGroup().name - keyvaultBackendCertDataSecretName: (!enableAppGWIngress || (appGatewayCertificateOption == const_appGatewaySSLCertOptionHaveKeyVault)) ? keyVaultSSLBackendRootCertDataSecretName : appgwSecretDeployment.outputs.sslBackendCertDataSecretName - keyVaultSSLCertDataSecretName: (!enableAppGWIngress || (appGatewayCertificateOption == const_appGatewaySSLCertOptionHaveKeyVault)) ? keyVaultSSLCertDataSecretName : appgwSecretDeployment.outputs.sslCertDataSecretName - keyVaultSSLCertPasswordSecretName: (!enableAppGWIngress || (appGatewayCertificateOption == const_appGatewaySSLCertOptionHaveKeyVault)) ? keyVaultSSLCertPasswordSecretName : appgwSecretDeployment.outputs.sslCertPwdSecretName + identity: obj_uamiForDeploymentScript location: location lbSvcValues: lbSvcValues - servicePrincipal: servicePrincipal + newOrExistingVnetForApplicationGateway: newOrExistingVnetForApplicationGateway + vnetRGNameForApplicationGateway: vnetRGNameForApplicationGateway + tagsByResource: _objTagsByResource useInternalLB: useInternalLB wlsDomainName: wlsDomainName - wlsDomainUID: wlsDomainUID + wlsDomainUID: wlsDomainUID } dependsOn: [ - appgwSecretDeployment + appgatewayDeployment + wlsDomainDeployment + wlsDomainWithCustomSSLDeployment ] } -module datasourceDeployment 'modules/_setupDBConnection.bicep' = if (enableDB) { +module datasourceDeployment 'modules/_setupDBConnection.bicep' = if (enableDB && !enablePswlessConnection) { name: 'datasource-deployment' params: { _artifactsLocation: _artifactsLocation _artifactsLocationSasToken: _artifactsLocationSasToken + _globalResourceNameSuffix: const_globalResourceNameSuffix _pidEnd: pids.outputs.dbEnd - _pidStart: pids.outputs.dbStart - aksClusterRGName: ref_wlsDomainDeployment.outputs.aksClusterRGName.value - aksClusterName: ref_wlsDomainDeployment.outputs.aksClusterName.value + _pidStart: pids.outputs.dbStart + aksClusterRGName: ref_wlsDomainDeployment.outputs.aksClusterRGName + aksClusterName: ref_wlsDomainDeployment.outputs.aksClusterName + azCliVersion: const_azcliVersion databaseType: databaseType dbConfigurationType: dbConfigurationType + dbDriverName: dbDriverName + dbGlobalTranPro: dbGlobalTranPro dbPassword: dbPassword + dbTestTableName: dbTestTableName dbUser: dbUser dsConnectionURL: dsConnectionURL - identity: identity + identity: obj_uamiForDeploymentScript jdbcDataSourceName: jdbcDataSourceName + location: location + tagsByResource: _objTagsByResource wlsDomainUID: wlsDomainUID wlsPassword: wlsPassword wlsUserName: wlsUserName @@ -554,18 +685,134 @@ module datasourceDeployment 'modules/_setupDBConnection.bicep' = if (enableDB) { ] } -output aksClusterName string = ref_wlsDomainDeployment.outputs.aksClusterName.value -output adminConsoleInternalUrl string = ref_wlsDomainDeployment.outputs.adminServerUrl.value -output adminConsoleExternalUrl string = const_enableNetworking ? networkingDeployment.outputs.adminConsoleExternalUrl : '' -output adminConsoleExternalSecuredUrl string = const_enableNetworking ? networkingDeployment.outputs.adminConsoleExternalSecuredUrl : '' -// If TLS/SSL enabled, only secured url is working, will not output HTTP url. -output adminRemoteConsoleUrl string = const_enableNetworking && !enableCustomSSL ? networkingDeployment.outputs.adminRemoteConsoleUrl : '' -output adminRemoteConsoleSecuredUrl string = const_enableNetworking ? networkingDeployment.outputs.adminRemoteConsoleSecuredUrl : '' -output adminServerT3InternalUrl string = ref_wlsDomainDeployment.outputs.adminServerT3InternalUrl.value -output adminServerT3ExternalUrl string = enableAdminT3Tunneling && const_enableNetworking ? format('{0}://{1}', enableCustomSSL ? 't3s' : 't3', networkingDeployment.outputs.adminServerT3ChannelUrl) : '' -output clusterInternalUrl string = ref_wlsDomainDeployment.outputs.clusterSVCUrl.value -output clusterExternalUrl string = const_enableNetworking ? networkingDeployment.outputs.clusterExternalUrl : '' -output clusterExternalSecuredUrl string = const_enableNetworking ? networkingDeployment.outputs.clusterExternalSecuredUrl : '' -output clusterT3InternalUrl string = ref_wlsDomainDeployment.outputs.clusterT3InternalUrl.value -output clusterT3ExternalUrl string = enableAdminT3Tunneling && const_enableNetworking ? format('{0}://{1}', enableCustomSSL ? 't3s' : 't3', networkingDeployment.outputs.clusterT3ChannelUrl) : '' +module passwordlessDatasourceDeployment 'modules/_setupPasswordlessDBConnection.bicep' = if (enableDB && enablePswlessConnection) { + name: 'passwordless-datasource-deployment' + params: { + _artifactsLocation: _artifactsLocation + _artifactsLocationSasToken: _artifactsLocationSasToken + _globalResourceNameSuffix: const_globalResourceNameSuffix + _pidEnd: pids.outputs.pswlessDbEnd + _pidStart: pids.outputs.pswlessDbStart + aksClusterRGName: ref_wlsDomainDeployment.outputs.aksClusterRGName + aksClusterName: ref_wlsDomainDeployment.outputs.aksClusterName + aksNodeRGName: ref_wlsDomainDeployment.outputs.aksNodeRgName + azCliVersion: const_azcliVersion + databaseType: databaseType + dbConfigurationType: dbConfigurationType + dbGlobalTranPro: dbGlobalTranPro + dbUser: dbUser + dbIdentity: dbIdentity + dsConnectionURL: dsConnectionURL + identity: obj_uamiForDeploymentScript + jdbcDataSourceName: jdbcDataSourceName + location: location + tagsByResource: _objTagsByResource + wlsDomainUID: wlsDomainUID + wlsPassword: wlsPassword + wlsUserName: wlsUserName + } + dependsOn: [ + networkingDeployment + ] +} + +/* +* To check if all the applciations in WLS cluster become ACTIVE state after all configurations are completed. +* This should be the last step. +*/ +module validateApplciations 'modules/_deployment-scripts/_ds-validate-applications.bicep' = if (const_bValidateApplications) { + name: 'validate-wls-application-status' + params: { + _artifactsLocation: _artifactsLocation + _artifactsLocationSasToken: _artifactsLocationSasToken + _globalResourceNameSuffix: const_globalResourceNameSuffix + aksClusterRGName: ref_wlsDomainDeployment.outputs.aksClusterRGName + aksClusterName: ref_wlsDomainDeployment.outputs.aksClusterName + azCliVersion: const_azcliVersion + identity: obj_uamiForDeploymentScript + location: location + tagsByResource: _objTagsByResource + wlsDomainUID: wlsDomainUID + wlsPassword: wlsPassword + wlsUserName: wlsUserName + } + dependsOn: [ + datasourceDeployment + passwordlessDatasourceDeployment + ] +} + +module horizontalAutoscaling 'modules/_enableAutoScaling.bicep' = if (enableAutoscaling) { + name: 'enable-horizontal-autoscaling' + params: { + _pidCPUUtilization: pids.outputs.cpuUtilization + _pidEnd: pids.outputs.autoScalingEnd + _globalResourceNameSuffix: const_globalResourceNameSuffix + _pidMemoryUtilization: pids.outputs.memoryUtilization + _pidStart: pids.outputs.autoScalingStart + _pidWme: pids.outputs.enableWlsMonitoringExporter + aksClusterName: ref_wlsDomainDeployment.outputs.aksClusterName + aksClusterRGName: ref_wlsDomainDeployment.outputs.aksClusterRGName + azCliVersion: const_azcliVersion + hpaScaleType: hpaScaleType + identity: obj_uamiForDeploymentScript + location: location + tagsByResource: _objTagsByResource + useHpa: useHpa + utilizationPercentage: hpaScaleType == 'cpu' ? averageCpuUtilization : averageMemoryUtilization + wlsClusterSize: wlsClusterSize + wlsDomainUID: wlsDomainUID + wlsPassword: wlsPassword + wlsUserName: wlsUserName + } + dependsOn: [ + validateApplciations + ] +} + +/* +* Query and output WebLogic domain configuration, including: +* - domain deployment description +* - image model +* - image properties +*/ +module queryWLSDomainConfig 'modules/_deployment-scripts/_ds-output-domain-configurations.bicep' = { + name: 'query-wls-domain-configurations' + params: { + _globalResourceNameSuffix: const_globalResourceNameSuffix + aksClusterRGName: ref_wlsDomainDeployment.outputs.aksClusterRGName + aksClusterName: ref_wlsDomainDeployment.outputs.aksClusterName + azCliVersion: const_azcliVersion + identity: obj_uamiForDeploymentScript + location: location + tagsByResource: _objTagsByResource + wlsClusterName: const_wlsClusterName + wlsDomainUID: wlsDomainUID + } + dependsOn: [ + horizontalAutoscaling + ] +} + +output aksClusterName string = ref_wlsDomainDeployment.outputs.aksClusterName +output adminConsoleInternalUrl string = ref_wlsDomainDeployment.outputs.adminServerEndPoint +output adminConsoleExternalUrl string = const_showAdminConsoleExUrl ? networkingDeployment.outputs.adminConsoleExternalEndpoint : '' +output adminConsoleExternalSecuredUrl string = const_showAdminConsoleExUrl ? networkingDeployment.outputs.adminConsoleExternalSecuredEndpoint : '' +// If TLS/SSL enabled, only secured url is working, will not output HTTP url. +output adminRemoteConsoleUrl string = const_showRemoteAdminConsoleExUrl ? networkingDeployment.outputs.adminRemoteConsoleEndpoint : '' +output adminRemoteConsoleSecuredUrl string = const_showRemoteAdminConsoleSecuredExUrl ? networkingDeployment.outputs.adminRemoteConsoleSecuredEndpoint : '' +output adminServerT3InternalUrl string = ref_wlsDomainDeployment.outputs.adminServerT3InternalEndPoint +output adminServerT3ExternalUrl string = enableAdminT3Tunneling && const_enableNetworking ? networkingDeployment.outputs.adminServerT3ChannelEndpoint : '' +output clusterInternalUrl string = ref_wlsDomainDeployment.outputs.clusterEndPoint +output clusterExternalUrl string = const_enableNetworking ? networkingDeployment.outputs.clusterExternalEndpoint : '' +output clusterExternalSecuredUrl string = const_enableNetworking ? networkingDeployment.outputs.clusterExternalSecuredEndpoint : '' +output clusterT3InternalUrl string = ref_wlsDomainDeployment.outputs.clusterT3InternalEndPoint +output clusterT3ExternalEndpoint string = enableClusterT3Tunneling && const_enableNetworking ? networkingDeployment.outputs.clusterT3ChannelEndpoint : '' +output kedaScalerServerAddress string = enableAutoscaling ? horizontalAutoscaling.outputs.kedaScalerServerAddress : '' +output shellCmdtoConnectAks string = format('az account set --subscription {0}; az aks get-credentials --resource-group {1} --name {2}', split(subscription().id, '/')[2], ref_wlsDomainDeployment.outputs.aksClusterRGName, ref_wlsDomainDeployment.outputs.aksClusterName) +output shellCmdtoOutputKedaScalerSample string = enableAutoscaling ? horizontalAutoscaling.outputs.base64ofKedaScalerSample : '' +output shellCmdtoOutputWlsDomainYaml string = queryWLSDomainConfig.outputs.shellCmdtoOutputWlsDomainYaml +output shellCmdtoOutputWlsImageModelYaml string = queryWLSDomainConfig.outputs.shellCmdtoOutputWlsImageModelYaml +output shellCmdtoOutputWlsImageProperties string = queryWLSDomainConfig.outputs.shellCmdtoOutputWlsImageProperties +output shellCmdtoOutputWlsVersionsandPatches string = queryWLSDomainConfig.outputs.shellCmdtoOutputWlsVersions diff --git a/weblogic-azure-aks/src/main/bicep/modules/_appGateway.bicep b/weblogic-azure-aks/src/main/bicep/modules/_appGateway.bicep new file mode 100644 index 000000000..e9b94c15a --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_appGateway.bicep @@ -0,0 +1,208 @@ +// Copyright (c) 2021, Oracle Corporation and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +param _pidAppgwEnd string = 'pid-networking-appgateway-end' +param _pidAppgwStart string = 'pid-networking-appgateway-start' +param _pidAppgwWithCustomCert string = 'pid-networking-appgateway-with-custom-certificate' +@allowed([ + 'haveCert' + 'generateCert' +]) +param appgwCertificateOption string +param appgwName string +param appgwPublicIPAddressName string +@secure() +param appgwSSLBackendRootCertData string +param appgwUsePrivateIP bool +param azCliVersion string = '' +param autoGeneratedSSLCertKeyVaultName string +param autoGeneratedSSLCertSecretName string +param dnsNameforApplicationGateway string = 'wlsgw' +param enableCustomSSL bool +param identity object = {} +param nsgName string +param location string +param newOrExistingVnetForApplicationGateway string +@secure() +param sslCertData string +param sslCertificateDeploymentName string +@secure() +param sslCertPswData string +param trustedRootCertificateDeploymentName string +param vnetForApplicationGateway object +param vnetRGNameForApplicationGateway string +@description('${label.tagsLabel}') +param tagsByResource object + +// To mitigate arm-ttk error: Type Mismatch: Parameter in nested template is defined as string, but the parent template defines it as bool. +var _appgwUsePrivateIP = appgwUsePrivateIP +var _selfSignedFrontendCertAndNoBackendCert = appgwCertificateOption == 'generateCert' && !enableCustomSSL +var _selfSignedFrontendCertAndBackendCert = appgwCertificateOption == 'generateCert' && enableCustomSSL +var _signedFrontendCertAndNoBackendCert = appgwCertificateOption == 'haveCert' && !enableCustomSSL +var _signedFrontendCertAndBackendCert = appgwCertificateOption == 'haveCert' && enableCustomSSL +var const_null = 'null' // To mitigate arm-ttk error: Parameter-Types-Should-Be-Consistent +var name_gatewayDeploymentPrefix = 'app-gateway-deployment-' +var ref_gatewayDeployment = _selfSignedFrontendCertAndNoBackendCert ? appgwDeployment1 : (_selfSignedFrontendCertAndBackendCert ? appgwDeployment2 : _signedFrontendCertAndNoBackendCert ? appgwDeployment3 : appgwDeployment4) + +module pidAppgwStart './_pids/_pid.bicep' = { + name: 'pid-app-gateway-start-deployment' + params: { + name: _pidAppgwStart + } +} +module pidAppgwWithCustomCertificate './_pids/_pid.bicep' = if (_signedFrontendCertAndNoBackendCert || _signedFrontendCertAndBackendCert) { + name: 'pid-app-gateway-with-custom-certificate' + params: { + name: _pidAppgwWithCustomCert + } +} + +// get key vault object from a resource group +resource existingKeyvault 'Microsoft.KeyVault/vaults@${azure.apiVersionForKeyVault}' existing = { + name: autoGeneratedSSLCertKeyVaultName +} + +module networkDeployment '_azure-resoruces/_vnetAppGateway.bicep' = { + name: 'vnet-application-gateway' + params: { + location: location + nsgName: nsgName + vnetForApplicationGateway: vnetForApplicationGateway + tagsByResource: tagsByResource + } + dependsOn: [ + pidAppgwStart + ] +} + +module queryPrivateIPFromSubnet '_deployment-scripts/_ds_query_available_private_ip_from_subnet.bicep' = if (appgwUsePrivateIP) { + name: 'query-available-private-ip-for-app-gateway' + params: { + azCliVersion: azCliVersion + identity: identity + location: location + subnetId: networkDeployment.outputs.subIdForApplicationGateway + knownIP: networkDeployment.outputs.knownIPAddress + tagsByResource: tagsByResource + } + dependsOn: [ + networkDeployment + ] +} + +module appgwDeployment1 '_azure-resoruces/_appgateway.bicep' = if (_selfSignedFrontendCertAndNoBackendCert) { + name: '${name_gatewayDeploymentPrefix}1' + params: { + dnsNameforApplicationGateway: dnsNameforApplicationGateway + enableCustomSSL: enableCustomSSL + gatewayName: appgwName + gatewayPublicIPAddressName: appgwPublicIPAddressName + gatewaySubnetId: networkDeployment.outputs.subIdForApplicationGateway + gatewaySslCertName: sslCertificateDeploymentName + gatewayTrustedRootCertName: trustedRootCertificateDeploymentName + location: location + noSslCertPsw: true + sslCertData: existingKeyvault.getSecret(autoGeneratedSSLCertSecretName) + sslCertPswData: const_null + staticPrivateFrontentIP: _appgwUsePrivateIP ? queryPrivateIPFromSubnet.outputs.privateIP : '' + trustedRootCertData: const_null + usePrivateIP: appgwUsePrivateIP + tagsByResource: tagsByResource + } + dependsOn: [ + queryPrivateIPFromSubnet + ] +} + +module appgwDeployment2 '_azure-resoruces/_appgateway.bicep' = if (_selfSignedFrontendCertAndBackendCert) { + name: '${name_gatewayDeploymentPrefix}2' + params: { + dnsNameforApplicationGateway: dnsNameforApplicationGateway + enableCustomSSL: enableCustomSSL + gatewayName: appgwName + gatewayPublicIPAddressName: appgwPublicIPAddressName + gatewaySubnetId: networkDeployment.outputs.subIdForApplicationGateway + gatewaySslCertName: sslCertificateDeploymentName + gatewayTrustedRootCertName: trustedRootCertificateDeploymentName + location: location + noSslCertPsw: true + sslCertData: existingKeyvault.getSecret(autoGeneratedSSLCertSecretName) + sslCertPswData: const_null + staticPrivateFrontentIP: _appgwUsePrivateIP ? queryPrivateIPFromSubnet.outputs.privateIP : '' + trustedRootCertData: appgwSSLBackendRootCertData + usePrivateIP: appgwUsePrivateIP + tagsByResource: tagsByResource + } + dependsOn: [ + queryPrivateIPFromSubnet + ] +} + +module appgwDeployment3 '_azure-resoruces/_appgateway.bicep' = if (_signedFrontendCertAndNoBackendCert) { + name: '${name_gatewayDeploymentPrefix}3' + params: { + dnsNameforApplicationGateway: dnsNameforApplicationGateway + enableCustomSSL: enableCustomSSL + gatewayName: appgwName + gatewayPublicIPAddressName: appgwPublicIPAddressName + gatewaySubnetId: networkDeployment.outputs.subIdForApplicationGateway + gatewaySslCertName: sslCertificateDeploymentName + gatewayTrustedRootCertName: trustedRootCertificateDeploymentName + location: location + sslCertData: sslCertData + sslCertPswData: sslCertPswData + staticPrivateFrontentIP: _appgwUsePrivateIP ? queryPrivateIPFromSubnet.outputs.privateIP : '' + trustedRootCertData: const_null + usePrivateIP: appgwUsePrivateIP + tagsByResource: tagsByResource + } + dependsOn: [ + queryPrivateIPFromSubnet + ] +} + +module appgwDeployment4 '_azure-resoruces/_appgateway.bicep' = if (_signedFrontendCertAndBackendCert) { + name: '${name_gatewayDeploymentPrefix}4' + params: { + dnsNameforApplicationGateway: dnsNameforApplicationGateway + enableCustomSSL: enableCustomSSL + gatewayName: appgwName + gatewayPublicIPAddressName: appgwPublicIPAddressName + gatewaySubnetId: networkDeployment.outputs.subIdForApplicationGateway + gatewaySslCertName: sslCertificateDeploymentName + gatewayTrustedRootCertName: trustedRootCertificateDeploymentName + location: location + sslCertData: sslCertData + sslCertPswData: sslCertPswData + staticPrivateFrontentIP: _appgwUsePrivateIP ? queryPrivateIPFromSubnet.outputs.privateIP : '' + trustedRootCertData: appgwSSLBackendRootCertData + usePrivateIP: appgwUsePrivateIP + tagsByResource: tagsByResource + } + dependsOn: [ + queryPrivateIPFromSubnet + ] +} + +module pidAppgwEnd './_pids/_pid.bicep' = { + name: 'pid-app-gateway-end-deployment' + params: { + name: _pidAppgwEnd + } + dependsOn: [ + appgwDeployment1 + appgwDeployment2 + appgwDeployment3 + appgwDeployment4 + ] +} + +output appGatewayAlias string = ref_gatewayDeployment.outputs.appGatewayAlias +output appGatewayId string = ref_gatewayDeployment.outputs.appGatewayId +output appGatewayName string = ref_gatewayDeployment.outputs.appGatewayName +output appGatewayURL string = uri(ref_gatewayDeployment.outputs.appGatewayURL, '') +output appGatewaySecuredURL string = uri(ref_gatewayDeployment.outputs.appGatewaySecuredURL, '') +// To mitigate ARM-TTK error: Control Named vnetForApplicationGateway must output the resourceGroup property when hideExisting is false +output vnetResourceGroupName string = vnetRGNameForApplicationGateway +// To mitigate ARM-TTK error: Control Named vnetForApplicationGateway must output the newOrExisting property when hideExisting is false +output newOrExisting string = newOrExistingVnetForApplicationGateway diff --git a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_acr.bicep b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_acr.bicep index ed3ce91aa..297f81567 100644 --- a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_acr.bicep +++ b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_acr.bicep @@ -1,14 +1,13 @@ // Copyright (c) 2021, Oracle Corporation and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -param acrNamePrefix string = 'wlsaksacr' -param location string = 'eastus' -param utcValue string = utcNow() +param acrName string +param location string +@description('${label.tagsLabel}') +param tagsByResource object -var name_acr= '${acrNamePrefix}${uniqueString(utcValue)}' - -resource registries 'Microsoft.ContainerRegistry/registries@2020-11-01-preview' = { - name: name_acr +resource registries 'Microsoft.ContainerRegistry/registries@${azure.apiVersionForContainerRegistries}' = { + name: acrName location: location sku: { name: 'Standard' @@ -38,6 +37,7 @@ resource registries 'Microsoft.ContainerRegistry/registries@2020-11-01-preview' zoneRedundancy: 'Disabled' anonymousPullEnabled: false } + tags: tagsByResource['${identifier.registries}'] } -output acrName string = name_acr +output acrName string = acrName diff --git a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_aks.bicep b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_aks.bicep index b2bbc5cf6..021434135 100644 --- a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_aks.bicep +++ b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_aks.bicep @@ -1,4 +1,4 @@ -// Copyright (c) 2021, Oracle Corporation and/or its affiliates. +// Copyright (c) 2021, 2024, Oracle Corporation and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. @description('true to use resource or workspace permissions. false to require workspace permissions.') @@ -7,36 +7,31 @@ param aciResourcePermissions bool = true param aciRetentionInDays int = 120 @description('Pricing tier: PerGB2018 or legacy tiers (Free, Standalone, PerNode, Standard or Premium) which are not available to all customers.') param aciWorkspaceSku string = 'pergb2018' +param agentAvailabilityZones array = [] @maxLength(12) @minLength(1) @description('The name for this node pool. Node pool must contain only lowercase letters and numbers. For Linux node pools the name cannot be longer than 12 characters.') -param aksAgentPoolName string = 'agentpool' +param aksAgentPoolName string = 'nodepool1' @maxValue(10000) @minValue(1) @description('The number of nodes that should be created along with the cluster. You will be able to resize the cluster later.') param aksAgentPoolNodeCount int = 3 +param aksAgentPoolNodeMaxCount int = 5 @description('The size of the virtual machines that will form the nodes in the cluster. This cannot be changed after creating the cluster') param aksAgentPoolVMSize string = 'Standard_DS2_v2' @description('Prefix for cluster name. Only The name can contain only letters, numbers, underscores and hyphens. The name must start with letter or number.') -param aksClusterNamePrefix string = 'wlsonaks' +param aksClusterName string param aksVersion string = 'default' @description('In addition to the CPU and memory metrics included in AKS by default, you can enable Container Insights for more comprehensive data on the overall performance and health of your cluster. Billing is based on data ingestion and retention settings.') param enableAzureMonitoring bool = false -param location string = 'eastus' +param location string +@description('${label.tagsLabel}') +param tagsByResource object param utcValue string = utcNow() var const_aksAgentPoolOSDiskSizeGB = 128 -var const_aksAgentPoolMaxPods = 110 -var const_aksAvailabilityZones = [ - '1' - '2' - '3' -] var name_aciWorkspace = 'Workspace-${guid(utcValue)}-${location}' // Generate a unique AKS name scoped to subscription. -// Create different cluster name for different deployment to avoid template validation error. -var name_aksClusterNameDefault = '${aksClusterNamePrefix}0${uniqueString(utcValue)}' -var name_aksClusterNameForSV = '${aksClusterNamePrefix}1${uniqueString(utcValue)}' var obj_aciDisableOmsAgent = { enabled: false } @@ -47,9 +42,10 @@ var obj_aciEnableOmsAgent = { } } -resource azureMonitoringWorkspace 'Microsoft.OperationalInsights/workspaces@2020-08-01' = if (enableAzureMonitoring) { +resource azureMonitoringWorkspace 'Microsoft.OperationalInsights/workspaces@${azure.apiVersionForInsightsWorkspaces}' = if (enableAzureMonitoring) { name: name_aciWorkspace location: location + tags: tagsByResource['${identifier.workspaces}'] properties: { sku: { name: aciWorkspaceSku @@ -63,25 +59,29 @@ resource azureMonitoringWorkspace 'Microsoft.OperationalInsights/workspaces@2020 } } -resource aksClusterDefault 'Microsoft.ContainerService/managedClusters@2021-02-01' = if (contains(aksVersion, 'default')) { - name: name_aksClusterNameDefault +resource aksCluster 'Microsoft.ContainerService/managedClusters@${azure.apiVersionForManagedClusters}' = { + name: aksClusterName location: location + tags: tagsByResource['${identifier.managedClusters}'] properties: { - dnsPrefix: '${name_aksClusterNameDefault}-dns' + kubernetesVersion: aksVersion + dnsPrefix: '${aksClusterName}-dns' agentPoolProfiles: [ { name: aksAgentPoolName + enableAutoScaling: true + minCount: aksAgentPoolNodeCount + maxCount: aksAgentPoolNodeMaxCount count: aksAgentPoolNodeCount vmSize: aksAgentPoolVMSize osDiskSizeGB: const_aksAgentPoolOSDiskSizeGB osDiskType: 'Managed' kubeletDiskType: 'OS' - maxPods: const_aksAgentPoolMaxPods type: 'VirtualMachineScaleSets' - availabilityZones: const_aksAvailabilityZones - nodeLabels: {} + availabilityZones: agentAvailabilityZones mode: 'System' osType: 'Linux' + tags: tagsByResource['${identifier.managedClusters}'] } ] addonProfiles: { @@ -98,7 +98,7 @@ resource aksClusterDefault 'Microsoft.ContainerService/managedClusters@2021-02-0 } enableRBAC: true networkProfile: { - networkPlugin: 'kubenet' + networkPlugin: 'azure' loadBalancerSku: 'standard' } } @@ -108,52 +108,4 @@ resource aksClusterDefault 'Microsoft.ContainerService/managedClusters@2021-02-0 } } -resource aksCluster 'Microsoft.ContainerService/managedClusters@2021-02-01' = if (!contains(aksVersion, 'default')) { - name: name_aksClusterNameForSV - location: location - properties: { - kubernetesVersion: '${aksVersion}' - dnsPrefix: '${name_aksClusterNameForSV}-dns' - agentPoolProfiles: [ - { - name: aksAgentPoolName - count: aksAgentPoolNodeCount - vmSize: aksAgentPoolVMSize - osDiskSizeGB: const_aksAgentPoolOSDiskSizeGB - osDiskType: 'Managed' - kubeletDiskType: 'OS' - maxPods: const_aksAgentPoolMaxPods - type: 'VirtualMachineScaleSets' - availabilityZones: const_aksAvailabilityZones - nodeLabels: {} - mode: 'System' - osType: 'Linux' - } - ] - addonProfiles: { - KubeDashboard: { - enabled: false - } - azurepolicy: { - enabled: false - } - httpApplicationRouting: { - enabled: false - } - omsAgent: { - enabled: bool('${enableAzureMonitoring}') - } - } - enableRBAC: true - networkProfile: { - networkPlugin: 'kubenet' - loadBalancerSku: 'standard' - } - } - identity: { - // enable system identity. - type: 'SystemAssigned' - } -} - -output aksClusterName string = '${aksVersion}' == 'default' ? name_aksClusterNameDefault : name_aksClusterNameForSV +output aksNodeRgName string = aksCluster.properties.nodeResourceGroup diff --git a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_aksPodIdentity.bicep b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_aksPodIdentity.bicep new file mode 100644 index 000000000..9b440d89f --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_aksPodIdentity.bicep @@ -0,0 +1,36 @@ +/* + Copyright (c) 2021, Oracle and/or its affiliates. +Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +*/ + +param aksClusterName string = '' +param dbIdentity object = {} +param namespace string = 'sample-domain1-ns' +param podIdentityName string ='' +param podIdentitySelector string = '' +param location string + +var const_APIVersion = '2022-01-31-PREVIEW' + +resource configAKSPodIdentity 'Microsoft.ContainerService/managedClusters@${azure.apiVersionForManagedClusters}' = { + name: aksClusterName + location: location + properties: { + podIdentityProfile:{ + allowNetworkPluginKubenet: false + enabled: true + userAssignedIdentities: [ + { + bindingSelector: podIdentitySelector + identity: { + clientId: reference(items(dbIdentity.userAssignedIdentities)[0].key, const_APIVersion, 'full').properties.clientId + objectId: reference(items(dbIdentity.userAssignedIdentities)[0].key, const_APIVersion, 'full').properties.principalId + resourceId: items(dbIdentity.userAssignedIdentities)[0].key + } + name: podIdentityName + namespace: namespace + } + ] + } + } +} diff --git a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_appgateway.bicep b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_appgateway.bicep index ac81e0c38..beaa9cad8 100644 --- a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_appgateway.bicep +++ b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_appgateway.bicep @@ -3,101 +3,90 @@ @description('DNS for ApplicationGateway') param dnsNameforApplicationGateway string = take('wlsgw${uniqueString(utcValue)}', 63) +param enableCustomSSL bool = false +param gatewayName string @description('Public IP Name for the Application Gateway') -param gatewayPublicIPAddressName string = 'gwip' +param gatewayPublicIPAddressName string +param gatewaySubnetId string = '/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/resourcegroupname/providers/Microsoft.Network/virtualNetworks/vnetname/subnets/subnetname' +param gatewaySslCertName string = 'appGatewaySslCert' +param gatewayTrustedRootCertName string = 'appGatewayTrustedRootCert' +param location string +param noSslCertPsw bool = false +@secure() +param sslCertData string = newGuid() +@secure() +param sslCertPswData string = newGuid() +param staticPrivateFrontentIP string = '10.0.0.1' +@secure() +param trustedRootCertData string = newGuid() +param usePrivateIP bool = false +@description('${label.tagsLabel}') +param tagsByResource object param utcValue string = utcNow() -var const_subnetAddressPrefix = '172.16.0.0/28' -var const_virtualNetworkAddressPrefix = '172.16.0.0/24' -var name_appGateway = 'appgw${uniqueString(utcValue)}' -var name_appGatewaySubnet = 'appGatewaySubnet' +var const_sslCertPsw = (noSslCertPsw) ? '' : sslCertPswData var name_backendAddressPool = 'myGatewayBackendPool' var name_frontEndIPConfig = 'appGwPublicFrontendIp' +var name_frontEndPrivateIPConfig = 'appGwPrivateFrontendIp' var name_httpListener = 'HTTPListener' var name_httpPort = 'httpport' var name_httpSetting = 'myHTTPSetting' -var name_nsg = 'nsg${uniqueString(utcValue)}' -var name_virtualNetwork = 'vnet${uniqueString(utcValue)}' -var ref_appGatewaySubnet = resourceId('Microsoft.Network/virtualNetworks/subnets', name_virtualNetwork, name_appGatewaySubnet) -var ref_backendAddressPool = resourceId('Microsoft.Network/applicationGateways/backendAddressPools', name_appGateway, name_backendAddressPool) -var ref_backendHttpSettings = resourceId('Microsoft.Network/applicationGateways/backendHttpSettingsCollection', name_appGateway, name_httpSetting) -var ref_frontendHTTPPort = resourceId('Microsoft.Network/applicationGateways/frontendPorts', name_appGateway, name_httpPort) -var ref_frontendIPConfiguration = resourceId('Microsoft.Network/applicationGateways/frontendIPConfigurations', name_appGateway, name_frontEndIPConfig) -var ref_httpListener = resourceId('Microsoft.Network/applicationGateways/httpListeners', name_appGateway, name_httpListener) - -resource nsg 'Microsoft.Network/networkSecurityGroups@2020-07-01' = { - name: name_nsg - location: resourceGroup().location - properties: { - securityRules: [ - { - properties: { - protocol: 'Tcp' - sourcePortRange: '*' - destinationPortRange: '65200-65535' - sourceAddressPrefix: 'GatewayManager' - destinationAddressPrefix: '*' - access: 'Allow' - priority: 500 - direction: 'Inbound' - } - name: 'ALLOW_APPGW' - } - { - properties: { - protocol: 'Tcp' - sourcePortRange: '*' - sourceAddressPrefix: 'Internet' - destinationAddressPrefix: '*' - access: 'Allow' - priority: 510 - direction: 'Inbound' - sourcePortRanges: [] - destinationPortRanges: [ - '80' - '443' - ] - sourceAddressPrefixes: [] - destinationAddressPrefixes: [] - } - name: 'ALLOW_HTTP_ACCESS' +var ref_backendAddressPool = resourceId('Microsoft.Network/applicationGateways/backendAddressPools', gatewayName, name_backendAddressPool) +var ref_backendHttpSettings = resourceId('Microsoft.Network/applicationGateways/backendHttpSettingsCollection', gatewayName, name_httpSetting) +var ref_frontendHTTPPort = resourceId('Microsoft.Network/applicationGateways/frontendPorts', gatewayName, name_httpPort) +var ref_frontendIPConfiguration = resourceId('Microsoft.Network/applicationGateways/frontendIPConfigurations', gatewayName, name_frontEndIPConfig) +var ref_httpListener = resourceId('Microsoft.Network/applicationGateways/httpListeners', gatewayName, name_httpListener) +var ref_publicIPAddress = resourceId('Microsoft.Network/publicIPAddresses', gatewayPublicIPAddressName) +var obj_backendTrustedRootCerts = [ + { + name: gatewayTrustedRootCertName + properties: { + data: trustedRootCertData + } + } +] +var obj_frontendIPConfigurations1 = [ + { + name: name_frontEndIPConfig + properties: { + publicIPAddress: { + id: ref_publicIPAddress } - ] + } } -} - -resource vnet 'Microsoft.Network/virtualNetworks@2020-07-01' = { - name: name_virtualNetwork - location: resourceGroup().location - properties: { - addressSpace: { - addressPrefixes: [ - const_virtualNetworkAddressPrefix - ] +] +var obj_frontendIPConfigurations2 = [ + { + name: name_frontEndIPConfig + properties: { + publicIPAddress: { + id: ref_publicIPAddress + } } - subnets: [ - { - name: name_appGatewaySubnet - properties: { - addressPrefix: const_subnetAddressPrefix - networkSecurityGroup: { - id: nsg.id - } - } + } + { + name: name_frontEndPrivateIPConfig + properties: { + privateIPAllocationMethod: 'Static' + privateIPAddress: staticPrivateFrontentIP + subnet: { + id: gatewaySubnetId } - ] + } } - dependsOn: [ - nsg - ] +] + +var obj_tagIngress = { + 'managed-by-k8s-ingress': 'true' } -resource gatewayPublicIP 'Microsoft.Network/publicIPAddresses@2020-07-01' = { +resource gatewayPublicIP 'Microsoft.Network/publicIPAddresses@${azure.apiVersionForPublicIPAddresses}' = { name: gatewayPublicIPAddressName sku: { name: 'Standard' } - location: resourceGroup().location + location: location + tags: tagsByResource['${identifier.publicIPAddresses}'] properties: { publicIPAllocationMethod: 'Static' dnsSettings: { @@ -106,37 +95,36 @@ resource gatewayPublicIP 'Microsoft.Network/publicIPAddresses@2020-07-01' = { } } -resource appGateway 'Microsoft.Network/applicationGateways@2020-07-01' = { - name: name_appGateway - location: resourceGroup().location - tags: { - 'managed-by-k8s-ingress': 'true' - } +resource wafv2AppGateway 'Microsoft.Network/applicationGateways@${azure.apiVersionForApplicationGateways}' = { + name: gatewayName + location: location + tags: union(tagsByResource['${identifier.applicationGateways}'], obj_tagIngress) properties: { sku: { name: 'WAF_v2' tier: 'WAF_v2' } - gatewayIPConfigurations: [ + sslCertificates: [ { - name: 'appGatewayIpConfig' + name: gatewaySslCertName properties: { - subnet: { - id: ref_appGatewaySubnet - } + data: sslCertData + password: const_sslCertPsw } } ] - frontendIPConfigurations: [ + trustedRootCertificates: enableCustomSSL ? obj_backendTrustedRootCerts : [] + gatewayIPConfigurations: [ { - name: name_frontEndIPConfig + name: 'appGatewayIpConfig' properties: { - publicIPAddress: { - id: gatewayPublicIP.id + subnet: { + id: gatewaySubnetId } } } ] + frontendIPConfigurations: usePrivateIP ? obj_frontendIPConfigurations2 : obj_frontendIPConfigurations1 frontendPorts: [ { name: name_httpPort @@ -148,9 +136,6 @@ resource appGateway 'Microsoft.Network/applicationGateways@2020-07-01' = { backendAddressPools: [ { name: 'myGatewayBackendPool' - properties: { - backendAddresses: [] - } } ] httpListeners: [ @@ -180,6 +165,7 @@ resource appGateway 'Microsoft.Network/applicationGateways@2020-07-01' = { { name: 'HTTPRoutingRule' properties: { + priority: 3 httpListener: { id: ref_httpListener } @@ -192,6 +178,12 @@ resource appGateway 'Microsoft.Network/applicationGateways@2020-07-01' = { } } ] + webApplicationFirewallConfiguration: { + enabled: true + firewallMode: 'Prevention' + ruleSetType: 'OWASP' + ruleSetVersion: '3.0' + } enableHttp2: false autoscaleConfiguration: { minCapacity: 2 @@ -199,12 +191,12 @@ resource appGateway 'Microsoft.Network/applicationGateways@2020-07-01' = { } } dependsOn: [ - vnet + gatewayPublicIP ] } -output appGatewayAlias string = reference(gatewayPublicIP.id).dnsSettings.fqdn -output appGatewayName string = name_appGateway -output appGatewayURL string = 'http://${reference(gatewayPublicIP.id).dnsSettings.fqdn}/' -output appGatewaySecuredURL string = 'https://${reference(gatewayPublicIP.id).dnsSettings.fqdn}/' -output vnetName string = name_virtualNetwork +output appGatewayAlias string = usePrivateIP ? staticPrivateFrontentIP : reference(gatewayPublicIP.id).dnsSettings.fqdn +output appGatewayId string = wafv2AppGateway.id +output appGatewayName string = gatewayName +output appGatewayURL string = uri(format('http://{0}/', usePrivateIP ? staticPrivateFrontentIP : reference(gatewayPublicIP.id).dnsSettings.fqdn), '') +output appGatewaySecuredURL string = uri(format('https://{0}/', usePrivateIP ? staticPrivateFrontentIP : reference(gatewayPublicIP.id).dnsSettings.fqdn), '') diff --git a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_keyvault/_keyvaultWithNewCert.bicep b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_autoGeneratedPfxCertInKeyVault.bicep similarity index 85% rename from weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_keyvault/_keyvaultWithNewCert.bicep rename to weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_autoGeneratedPfxCertInKeyVault.bicep index eb508ee6a..c7f4022f2 100644 --- a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_keyvault/_keyvaultWithNewCert.bicep +++ b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_autoGeneratedPfxCertInKeyVault.bicep @@ -1,11 +1,14 @@ // Copyright (c) 2021, Oracle Corporation and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +param _globalResourceNameSuffix string @description('Managed identity to be used for the deployment script. Currently, only user-assigned MSI is supported.') -param identity object +param identity object = {} @description('Used to name the new Azure Key Vault resoure.') -param keyVaultName string = 'wls-kv-${uniqueString(utcValue)}' +param keyVaultName string = 'wlskv${uniqueString(utcValue)}' + +param location string @description('Access permission of the key vault, will applied to all access policies.') param permission object = { @@ -24,14 +27,20 @@ param secretName string = 'mySelfSignedCertificate' param sku string = 'Standard' @description('Subject name to create a new certificate, example: \'CN=contoso.com\'.') -param subjectName string +param subjectName string = 'contoso.xyz' +@description('${label.tagsLabel}') +param tagsByResource object param utcValue string = utcNow() +var obj_extraTag= { + 'created-by-azure-weblogic': utcValue +} var const_identityId = '${substring(string(identity.userAssignedIdentities), indexOf(string(identity.userAssignedIdentities), '"') + 1, lastIndexOf(string(identity.userAssignedIdentities), '"') - (indexOf(string(identity.userAssignedIdentities), '"') + 1))}' -resource keyvault 'Microsoft.KeyVault/vaults@2019-09-01' = { +resource keyvault 'Microsoft.KeyVault/vaults@${azure.apiVersionForKeyVault}' = { name: keyVaultName - location: resourceGroup().location + location: location + tags: union(tagsByResource['${identifier.vaults}'], obj_extraTag) properties: { sku: { family: 'A' @@ -50,20 +59,19 @@ resource keyvault 'Microsoft.KeyVault/vaults@2019-09-01' = { enabledForDiskEncryption: false enabledForTemplateDeployment: true enableSoftDelete: true - } - tags:{ - 'managed-by-azure-weblogic': utcValue + enableRbacAuthorization: false } } -resource createAddCertificate 'Microsoft.Resources/deploymentScripts@2020-10-01' = { - name: 'ds-create-add-appgw-certificate' - location: resourceGroup().location +resource createAddCertificate 'Microsoft.Resources/deploymentScripts@${azure.apiVersionForDeploymentScript}' = { + name: 'ds-create-add-appgw-certificate-${_globalResourceNameSuffix}' + location: location identity: identity kind: 'AzurePowerShell' + tags: tagsByResource['${identifier.deploymentScripts}'] properties: { forceUpdateTag: utcValue - azPowerShellVersion: '5.0' + azPowerShellVersion: '${azure.powershell.version}' timeout: 'PT30M' arguments: ' -vaultName ${keyVaultName} -certificateName ${secretName} -subjectName ${subjectName}' scriptContent: '\n param(\n [string] [Parameter(Mandatory=$true)] $vaultName,\n [string] [Parameter(Mandatory=$true)] $certificateName,\n [string] [Parameter(Mandatory=$true)] $subjectName\n )\n\n $ErrorActionPreference = \'Stop\'\n $DeploymentScriptOutputs = @{}\n\n $existingCert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName\n\n if ($existingCert -and $existingCert.Certificate.Subject -eq $subjectName) {\n\n Write-Host \'Certificate $certificateName in vault $vaultName is already present.\'\n\n $DeploymentScriptOutputs[\'certThumbprint\'] = $existingCert.Thumbprint\n $existingCert | Out-String\n }\n else {\n $policy = New-AzKeyVaultCertificatePolicy -SubjectName $subjectName -IssuerName Self -ValidityInMonths 12 -Verbose\n\n # private key is added as a secret that can be retrieved in the ARM template\n Add-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName -CertificatePolicy $policy -Verbose\n\n $newCert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName\n\n # it takes a few seconds for KeyVault to finish\n $tries = 0\n do {\n Write-Host \'Waiting for certificate creation completion...\'\n Start-Sleep -Seconds 10\n $operation = Get-AzKeyVaultCertificateOperation -VaultName $vaultName -Name $certificateName\n $tries++\n\n if ($operation.Status -eq \'failed\')\n {\n throw \'Creating certificate $certificateName in vault $vaultName failed with error $($operation.ErrorMessage)\'\n }\n\n if ($tries -gt 120)\n {\n throw \'Timed out waiting for creation of certificate $certificateName in vault $vaultName\'\n }\n } while ($operation.Status -ne \'completed\')\n\n $DeploymentScriptOutputs[\'certThumbprint\'] = $newCert.Thumbprint\n $newCert | Out-String\n }\n ' diff --git a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_dnsZones.bicep b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_dnsZones.bicep index c5dba80b3..18f740809 100644 --- a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_dnsZones.bicep +++ b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_dnsZones.bicep @@ -1,9 +1,12 @@ @description('Azure DNS Zone name.') param dnszoneName string +@description('${label.tagsLabel}') +param tagsByResource object -resource dnszoneName_resource 'Microsoft.Network/dnszones@2018-05-01' = { +resource dnszoneName_resource 'Microsoft.Network/dnszones@${azure.apiVersionForDNSZone}' = { name: dnszoneName location: 'global' + tags: tagsByResource['${identifier.dnszones}'] properties: { zoneType: 'Public' } diff --git a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_keyvault/_keyvaultForGatewayBackendCert.bicep b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_keyvault/_keyvaultForGatewayBackendCert.bicep deleted file mode 100644 index c5a2ab104..000000000 --- a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_keyvault/_keyvaultForGatewayBackendCert.bicep +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2021, Oracle Corporation and/or its affiliates. -// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. - -@description('Secret name of certificate data.') -param certificateDataName string - -@description('Certificate data to store in the secret') -param certificateDataValue string - -@description('Property to specify whether Azure Resource Manager is permitted to retrieve secrets from the key vault.') -param enabledForTemplateDeployment bool = true - -@description('Name of the vault') -param keyVaultName string - -@description('Price tier for Key Vault.') -param sku string - -param utcValue string = utcNow() - -resource keyvault 'Microsoft.KeyVault/vaults@2019-09-01' = { - name: keyVaultName - location: resourceGroup().location - properties: { - enabledForTemplateDeployment: enabledForTemplateDeployment - sku: { - name: sku - family: 'A' - } - accessPolicies: [] - tenantId: subscription().tenantId - } - tags:{ - 'managed-by-azure-weblogic': utcValue - } -} - -resource secretForCertificate 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = { - name: '${keyVaultName}/${certificateDataName}' - properties: { - value: certificateDataValue - } - dependsOn: [ - keyvault - ] -} - -output keyVaultName string = keyVaultName -output sslBackendCertDataSecretName string = certificateDataName diff --git a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_keyvault/_keyvaultForWLSSSLCert.bicep b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_keyvault/_keyvaultForWLSSSLCert.bicep deleted file mode 100644 index f32233ae9..000000000 --- a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_keyvault/_keyvaultForWLSSSLCert.bicep +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) 2021, Oracle Corporation and/or its affiliates. -// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. - -@description('Property to specify whether Azure Resource Manager is permitted to retrieve secrets from the key vault.') -param enabledForTemplateDeployment bool = true -@description('Name of the vault') -param keyVaultName string -@description('Price tier for Key Vault.') -param sku string -param utcValue string = utcNow() -param wlsIdentityKeyStoreData string -param wlsIdentityKeyStoreDataSecretName string -@secure() -param wlsIdentityKeyStorePassphrase string -param wlsIdentityKeyStorePassphraseSecretName string -param wlsPrivateKeyAlias string -param wlsPrivateKeyAliasSecretName string -@secure() -param wlsPrivateKeyPassPhrase string -param wlsPrivateKeyPassPhraseSecretName string -param wlsTrustKeyStoreData string -param wlsTrustKeyStoreDataSecretName string -@secure() -param wlsTrustKeyStorePassPhrase string -param wlsTrustKeyStorePassPhraseSecretName string - -resource keyvault 'Microsoft.KeyVault/vaults@2019-09-01' = { - name: keyVaultName - location: resourceGroup().location - properties: { - enabledForTemplateDeployment: enabledForTemplateDeployment - sku: { - name: sku - family: 'A' - } - accessPolicies: [] - tenantId: subscription().tenantId - } - tags:{ - 'managed-by-azure-weblogic': utcValue - } -} - -resource identityKeyStoreDataSecret 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = { - name: '${keyVaultName}/${wlsIdentityKeyStoreDataSecretName}' - properties: { - value: wlsIdentityKeyStoreData - } - dependsOn: [ - keyvault - ] -} - -resource identityKeyStorePswSecret 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = { - name: '${keyVaultName}/${wlsIdentityKeyStorePassphraseSecretName}' - properties: { - value: wlsIdentityKeyStorePassphrase - } - dependsOn: [ - keyvault - ] -} - -resource privateKeyAliasSecret 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = { - name: '${keyVaultName}/${wlsPrivateKeyAliasSecretName}' - properties: { - value: wlsPrivateKeyAlias - } - dependsOn: [ - keyvault - ] -} - -resource privateKeyPswSecret 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = { - name: '${keyVaultName}/${wlsPrivateKeyPassPhraseSecretName}' - properties: { - value: wlsPrivateKeyPassPhrase - } - dependsOn: [ - keyvault - ] -} - -resource trustKeyStoreDataSecret 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = { - name: '${keyVaultName}/${wlsTrustKeyStoreDataSecretName}' - properties: { - value: wlsTrustKeyStoreData - } - dependsOn: [ - keyvault - ] -} - -resource trustKeyStorePswSecret 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = { - name: '${keyVaultName}/${wlsTrustKeyStorePassPhraseSecretName}' - properties: { - value: wlsTrustKeyStorePassPhrase - } - dependsOn: [ - keyvault - ] -} - diff --git a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_keyvault/_keyvaultWithExistingCert.bicep b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_keyvault/_keyvaultWithExistingCert.bicep deleted file mode 100644 index 5b02d09f8..000000000 --- a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_keyvault/_keyvaultWithExistingCert.bicep +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2021, Oracle Corporation and/or its affiliates. -// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. - -@description('Secret name of certificate data.') -param certificateDataName string - -@description('Certificate data to store in the secret') -param certificateDataValue string - -@description('Secret name of certificate password.') -param certificatePasswordName string - -@description('Certificate password to store in the secret') -param certificatePasswordValue string - -@description('Property to specify whether Azure Resource Manager is permitted to retrieve secrets from the key vault.') -param enabledForTemplateDeployment bool = true - -@description('Name of the vault') -param keyVaultName string - -@description('Price tier for Key Vault.') -param sku string - -param utcValue string = utcNow() - -resource keyvault 'Microsoft.KeyVault/vaults@2019-09-01' = { - name: keyVaultName - location: resourceGroup().location - properties: { - enabledForTemplateDeployment: enabledForTemplateDeployment - sku: { - name: sku - family: 'A' - } - accessPolicies: [] - tenantId: subscription().tenantId - } - tags:{ - 'managed-by-azure-weblogic': utcValue - } -} - -resource secretForCertificate 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = { - name: '${keyVaultName}/${certificateDataName}' - properties: { - value: certificateDataValue - } - dependsOn: [ - keyvault - ] -} - -resource secretForCertPassword 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = { - name: '${keyVaultName}/${certificatePasswordName}' - properties: { - value: certificatePasswordValue - } - dependsOn: [ - keyvault - ] -} - -output keyVaultName string = keyVaultName -output sslCertDataSecretName string = certificateDataName -output sslCertPwdSecretName string = certificatePasswordName diff --git a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_keyvaultForGateway.bicep b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_keyvaultForGateway.bicep deleted file mode 100644 index 5e682f89a..000000000 --- a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_keyvaultForGateway.bicep +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2021, Oracle Corporation and/or its affiliates. -// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -// Deploy Application Gateway certificate secrets. - -@description('Backend certificate data to store in the secret') -param backendCertificateDataValue string - -@description('Certificate data to store in the secret') -param certificateDataValue string - -@description('Certificate password to store in the secret') -param certificatePasswordValue string - -@description('true to upload trusted root certificate') -param enableCustomSSL bool = false - -@description('Property to specify whether Azure Resource Manager is permitted to retrieve secrets from the key vault.') -param enabledForTemplateDeployment bool = true - -param identity object -param permission object = { - certificates: [ - 'get' - 'list' - 'update' - 'create' - ] -} - -@description('Price tier for Key Vault.') -param sku string = 'Standard' - -@description('Subject name to create a certificate.') -param subjectName string - -@description('If false, will create a certificate.') -param useExistingAppGatewaySSLCertificate bool = false - -@description('Current deployment time. Used as a tag in deployment script.') -param keyVaultName string = 'GEN_UNIQUE' - -var name_sslBackendCertSercretName= 'myAppGatewaySSLBackendRootCert' -var name_sslCertSecretName = 'myAppGatewaySSLCert' -var name_sslCertPasswordSecretName = 'myAppGatewaySSLCertPassword' - -module keyVaultwithSelfSignedAppGatewaySSLCert '_keyvault/_keyvaultWithNewCert.bicep' = if (!useExistingAppGatewaySSLCertificate) { - name: 'kv-appgw-selfsigned-certificate-deployment' - params: { - identity: identity - keyVaultName: keyVaultName - permission: permission - subjectName: subjectName - sku: sku - } -} - -module keyVaultwithExistingAppGatewaySSLCert '_keyvault/_keyvaultWithExistingCert.bicep' = if (useExistingAppGatewaySSLCertificate) { - name: 'kv-appgw-existing-certificate-deployment' - params: { - certificateDataName: name_sslCertSecretName - certificateDataValue: certificateDataValue - certificatePasswordName: name_sslCertPasswordSecretName - certificatePasswordValue: certificatePasswordValue - enabledForTemplateDeployment: enabledForTemplateDeployment - keyVaultName: keyVaultName - sku: sku - } -} - -module keyvaultBackendRootCert '_keyvault/_keyvaultForGatewayBackendCert.bicep' = if (enableCustomSSL) { - name: 'kv-appgw-e2e-ssl-backend-certificate' - params:{ - certificateDataName: name_sslBackendCertSercretName - certificateDataValue: backendCertificateDataValue - enabledForTemplateDeployment: enabledForTemplateDeployment - keyVaultName: keyVaultName - sku: sku - } - dependsOn:[ - keyVaultwithSelfSignedAppGatewaySSLCert - keyVaultwithExistingAppGatewaySSLCert - ] -} - -output keyVaultName string = (useExistingAppGatewaySSLCertificate ? keyVaultwithExistingAppGatewaySSLCert.outputs.keyVaultName : keyVaultwithSelfSignedAppGatewaySSLCert.outputs.keyVaultName) -output sslCertDataSecretName string = (useExistingAppGatewaySSLCertificate ? keyVaultwithExistingAppGatewaySSLCert.outputs.sslCertDataSecretName : keyVaultwithSelfSignedAppGatewaySSLCert.outputs.secretName) -output sslCertPwdSecretName string = (useExistingAppGatewaySSLCertificate ? keyVaultwithExistingAppGatewaySSLCert.outputs.sslCertPwdSecretName: '') -output sslBackendCertDataSecretName string = (enableCustomSSL) ? keyvaultBackendRootCert.outputs.sslBackendCertDataSecretName : '' - diff --git a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_storage.bicep b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_storage.bicep index a79884a9b..009b1a669 100644 --- a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_storage.bicep +++ b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_storage.bicep @@ -1,18 +1,24 @@ // Copyright (c) 2021, Oracle Corporation and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -param location string = 'eastus' -param storageAccountName string +param fileShareName string +param location string +param storageAccountName string = 'stg-contoso' +@description('${label.tagsLabel}') +param tagsByResource object param utcValue string = utcNow() var const_shareQuota = 5120 var const_sku = 'Standard_LRS' -var name_fileShare = 'weblogic' +var obj_extraTag = { + 'created-by-azure-weblogic': utcValue +} -resource storageAccount 'Microsoft.Storage/storageAccounts@2021-02-01' = { +resource storageAccount 'Microsoft.Storage/storageAccounts@${azure.apiVersionForStorage}' = { name: storageAccountName location: location kind: 'StorageV2' + tags: union(tagsByResource['${identifier.storageAccounts}'], obj_extraTag) sku: { name: const_sku tier: 'Standard' @@ -20,8 +26,6 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2021-02-01' = { properties: { networkAcls: { bypass: 'AzureServices' - virtualNetworkRules: [] - ipRules: [] defaultAction: 'Allow' } supportsHttpsTrafficOnly: true @@ -35,14 +39,11 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2021-02-01' = { keySource: 'Microsoft.Storage' } accessTier: 'Hot' - } - tags:{ - 'managed-by-azure-weblogic': utcValue - } + } } -resource fileService 'Microsoft.Storage/storageAccounts/fileServices/shares@2021-02-01' = { - name: '${storageAccount.name}/default/${name_fileShare}' +resource fileService 'Microsoft.Storage/storageAccounts/fileServices/shares@${azure.apiVersionForStorageFileService}' = { + name: '${storageAccount.name}/default/${fileShareName}' properties: { accessTier: 'TransactionOptimized' shareQuota: const_shareQuota diff --git a/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_vnetAppGateway.bicep b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_vnetAppGateway.bicep new file mode 100644 index 000000000..d08f3c1cc --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_azure-resoruces/_vnetAppGateway.bicep @@ -0,0 +1,107 @@ +// Copyright (c) 2021, Oracle Corporation and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +param location string +param nsgName string +param vnetForApplicationGateway object = { + name: 'wlsaks-app-gateway-vnet' + resourceGroup: resourceGroup().name + addressPrefixes: [ + '172.16.0.0/24' + ] + addressPrefix: '172.16.0.0/24' + newOrExisting: 'new' + subnets: { + gatewaySubnet: { + name: 'wlsaks-gateway-subnet' + addressPrefix: '172.16.0.0/24' + startAddress: '172.16.0.4' + } + } +} +@description('${label.tagsLabel}') +param tagsByResource object + +var const_subnetAddressPrefixes = vnetForApplicationGateway.subnets.gatewaySubnet.addressPrefix +var const_vnetAddressPrefixes = vnetForApplicationGateway.addressPrefixes +var const_newVnet = (vnetForApplicationGateway.newOrExisting == 'new') ? true : false +var name_subnet = vnetForApplicationGateway.subnets.gatewaySubnet.name +var name_vnet = vnetForApplicationGateway.name + +// Get existing VNET. +resource existingVnet 'Microsoft.Network/virtualNetworks@${azure.apiVersionForVirtualNetworks}' existing = if (!const_newVnet) { + name: name_vnet + scope: resourceGroup(vnetForApplicationGateway.resourceGroup) +} + +// Get existing subnet. +resource existingSubnet 'Microsoft.Network/virtualNetworks/subnets@${azure.apiVersionForVirtualNetworks}' existing = if (!const_newVnet) { + name: name_subnet + parent: existingVnet +} + +// Create new network security group. +resource nsg 'Microsoft.Network/networkSecurityGroups@${azure.apiVersionForNetworkSecurityGroups}' = if (const_newVnet) { + name: nsgName + location: location + tags: tagsByResource['${identifier.networkSecurityGroups}'] + properties: { + securityRules: [ + { + properties: { + protocol: 'Tcp' + sourcePortRange: '*' + destinationPortRange: '65200-65535' + sourceAddressPrefix: 'GatewayManager' + destinationAddressPrefix: '*' + access: 'Allow' + priority: 500 + direction: 'Inbound' + } + name: 'ALLOW_APPGW' + } + { + properties: { + protocol: 'Tcp' + sourcePortRange: '*' + sourceAddressPrefix: 'Internet' + destinationAddressPrefix: '*' + access: 'Allow' + priority: 510 + direction: 'Inbound' + destinationPortRanges: [ + '80' + '443' + ] + } + name: 'ALLOW_HTTP_ACCESS' + } + ] + } +} + +// Create new VNET and subnet. +resource newVnet 'Microsoft.Network/virtualNetworks@${azure.apiVersionForVirtualNetworks}' = if (const_newVnet) { + name: name_vnet + location: location + tags: tagsByResource['${identifier.virtualNetworks}'] + properties: { + addressSpace: { + addressPrefixes: const_vnetAddressPrefixes + } + subnets: [ + { + name: name_subnet + properties: { + addressPrefix: const_subnetAddressPrefixes + networkSecurityGroup: { + id: nsg.id + } + } + } + ] + } +} + +output subIdForApplicationGateway string = const_newVnet ? resourceId('Microsoft.Network/virtualNetworks/subnets', name_vnet, name_subnet) : existingSubnet.id +output knownIPAddress string = vnetForApplicationGateway.subnets.gatewaySubnet.startAddress diff --git a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-appgw-upload-trusted-root-certificate.bicep b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-appgw-upload-trusted-root-certificate.bicep deleted file mode 100644 index 416d93452..000000000 --- a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-appgw-upload-trusted-root-certificate.bicep +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2021, Oracle Corporation and/or its affiliates. -// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. - -param appgwName string -@secure() -param sslBackendRootCertData string = newGuid() -param identity object -param utcValue string = utcNow() - -var const_arguments = '${resourceGroup().name} ${appgwName} ${sslBackendRootCertData}' -var const_azcliVersion='2.15.0' -var const_deploymentName='ds-upload-trusted-root-certificatre-to-gateway' - -resource deploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { - name: const_deploymentName - location: resourceGroup().location - kind: 'AzureCLI' - identity: identity - properties: { - azCliVersion: const_azcliVersion - arguments: const_arguments - scriptContent: loadTextContent('../../../arm/scripts/uploadAppGatewayTrutedRootCert.sh') - cleanupPreference: 'OnSuccess' - retentionInterval: 'P1D' - forceUpdateTag: utcValue - } -} diff --git a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-create-networking.bicep b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-create-networking.bicep index 179faac22..901fe4f83 100644 --- a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-create-networking.bicep +++ b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-create-networking.bicep @@ -1,29 +1,25 @@ // Copyright (c) 2021, Oracle Corporation and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -param _artifactsLocation string +param _artifactsLocation string = deployment().properties.templateLink.uri @secure() param _artifactsLocationSasToken string = '' +param _globalResourceNameSuffix string param appgwAlias string = 'appgw-contoso-alias' param appgwName string = 'appgw-contoso' -@allowed([ - 'haveCert' - 'haveKeyVault' - 'generateCert' -]) @description('Three scenarios we support for deploying app gateway') -param appgwCertificateOption string = 'haveCert' param appgwForAdminServer bool = true param appgwForRemoteConsole bool = true -@secure() -param appgwFrontendSSLCertData string = newGuid() -@secure() -param appgwFrontendSSLCertPsw string = newGuid() +param appgwSslCert string = '' +param appgwTrustedRootCert string = '' +param appgwUsePrivateIP bool = false param aksClusterRGName string = 'aks-contoso-rg' param aksClusterName string = 'aks-contoso' +param azCliVersion string = '' +param createAKSCluster bool param dnszoneAdminConsoleLabel string = 'admin' -param dnszoneAdminT3ChannelLabel string ='admin-t3' +param dnszoneAdminT3ChannelLabel string = 'admin-t3' param dnszoneClusterLabel string = 'www' param dnszoneClusterT3ChannelLabel string = 'cluster-t3' param dnszoneName string = 'contoso.xyz' @@ -32,43 +28,136 @@ param enableAppGWIngress bool = false param enableCookieBasedAffinity bool = false param enableCustomSSL bool = false param enableDNSConfiguration bool = false -param identity object +param identity object = {} param lbSvcValues array = [] -param location string = 'eastus' -@secure() -param servicePrincipal string = newGuid() +param location string param useInternalLB bool = false param utcValue string = utcNow() -param vnetName string = 'vnet-contoso' -param wlsDomainName string = 'domain1' +param wlsDomainName string = 'domain1' param wlsDomainUID string = 'sample-domain1' +@description('${label.tagsLabel}') +param tagsByResource object -var const_appgwHelmConfigTemplate='appgw-helm-config.yaml.template' -var const_appgwSARoleBindingFile='appgw-ingress-clusterAdmin-roleBinding.yaml' -var const_arguments = '${aksClusterRGName} ${aksClusterName} ${wlsDomainName} ${wlsDomainUID} "${string(lbSvcValues)}" ${enableAppGWIngress} ${subscription().id} ${resourceGroup().name} ${appgwName} ${vnetName} ${string(servicePrincipal)} ${appgwForAdminServer} ${enableDNSConfiguration} ${dnszoneRGName} ${dnszoneName} ${dnszoneAdminConsoleLabel} ${dnszoneClusterLabel} ${appgwAlias} ${useInternalLB} ${appgwFrontendSSLCertData} ${appgwFrontendSSLCertPsw} ${appgwCertificateOption} ${enableCustomSSL} ${enableCookieBasedAffinity} ${appgwForRemoteConsole} ${dnszoneAdminT3ChannelLabel} ${dnszoneClusterT3ChannelLabel}' var const_commonScript = 'common.sh' var const_createDnsRecordScript = 'createDnsRecord.sh' var const_createLbSvcScript = 'createLbSvc.sh' var const_createGatewayIngressSvcScript = 'createAppGatewayIngress.sh' var const_scriptLocation = uri(_artifactsLocation, 'scripts/') -var const_setupNetworkingScript= 'setupNetworking.sh' -var const_primaryScript = 'invokeSetupNetworking.sh' -var const_utilityScript= 'utility.sh' -var name_deploymentName='ds-networking-deployment' +var const_primaryScript = 'setupNetworking.sh' +var const_utilityScript = 'utility.sh' -resource deploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { - name: 'ds-networking-deployment' +resource deploymentScript 'Microsoft.Resources/deploymentScripts@${azure.apiVersionForDeploymentScript}' = { + name: 'ds-networking-deployment-${_globalResourceNameSuffix}' location: location kind: 'AzureCLI' identity: identity + tags: tagsByResource['${identifier.deploymentScripts}'] properties: { - azCliVersion: '2.15.0' - arguments: const_arguments + azCliVersion: azCliVersion + environmentVariables: [ + { + name: 'AKS_CLUSTER_RG_NAME' + value: aksClusterRGName + } + { + name: 'AKS_CLUSTER_NAME' + value: aksClusterName + } + { + name: 'APPGW_SSL_CERT_NAME' + value: appgwSslCert + } + { + name: 'APPGW_TRUSTED_ROOT_CERT_NAME' + value: appgwTrustedRootCert + } + { + name: 'APPGW_NAME' + value: appgwName + } + { + name: 'APPGW_USE_PRIVATE_IP' + value: string(appgwUsePrivateIP) + } + { + name: 'APPGW_FOR_ADMIN_SERVER' + value: string(appgwForAdminServer) + } + { + name: 'APPGW_FOR_REMOTE_CONSOLE' + value: string(appgwForRemoteConsole) + } + { + name: 'APPGW_ALIAS' + value: appgwAlias + } + { + name: 'CREATE_AKS_CLUSTER' + value: string(createAKSCluster) + } + { + name: 'CURRENT_RG_NAME' + value: resourceGroup().name + } + { + name: 'DNS_ZONE_NAME' + value: dnszoneName + } + { + name: 'DNS_ZONE_RG_NAME' + value: dnszoneRGName + } + { + name: 'DNS_ADMIN_LABEL' + value: dnszoneAdminConsoleLabel + } + { + name: 'DNS_CLUSTER_LABEL' + value: dnszoneClusterLabel + } + { + name: 'DNS_ADMIN_T3_LABEL' + value: dnszoneAdminT3ChannelLabel + } + { + name: 'DNS_CLUSTER_T3_LABEL' + value: dnszoneClusterT3ChannelLabel + } + { + name: 'ENABLE_DNS_CONFIGURATION' + value: string(enableDNSConfiguration) + } + { + name: 'ENABLE_AGIC' + value: string(enableAppGWIngress) + } + { + name: 'ENABLE_CUSTOM_SSL' + value: string(enableCustomSSL) + } + { + name: 'ENABLE_COOKIE_BASED_AFFINITY' + value: string(enableCookieBasedAffinity) + } + { + name: 'LB_SVC_VALUES' + value: string(lbSvcValues) + } + { + name: 'USE_INTERNAL_LB' + value: string(useInternalLB) + } + { + name: 'WLS_DOMAIN_NAME' + value: wlsDomainName + } + { + name: 'WLS_DOMAIN_UID' + value: wlsDomainUID + } + ] primaryScriptUri: uri(const_scriptLocation, '${const_primaryScript}${_artifactsLocationSasToken}') supportingScriptUris: [ - uri(const_scriptLocation, '${const_setupNetworkingScript}${_artifactsLocationSasToken}') - uri(const_scriptLocation, '${const_appgwHelmConfigTemplate}${_artifactsLocationSasToken}') - uri(const_scriptLocation, '${const_appgwSARoleBindingFile}${_artifactsLocationSasToken}') uri(const_scriptLocation, '${const_commonScript}${_artifactsLocationSasToken}') uri(const_scriptLocation, '${const_utilityScript}${_artifactsLocationSasToken}') uri(const_scriptLocation, '${const_createDnsRecordScript}${_artifactsLocationSasToken}') @@ -81,12 +170,11 @@ resource deploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { } } -output adminConsoleLBUrl string = (!enableCustomSSL) && length(lbSvcValues) > 0 && (reference(name_deploymentName).outputs.adminConsoleEndpoint != 'null') ? format('http://{0}/',reference(name_deploymentName).outputs.adminConsoleEndpoint): '' -output adminConsoleLBSecuredUrl string = enableCustomSSL && length(lbSvcValues) > 0 && (reference(name_deploymentName).outputs.adminConsoleEndpoint != 'null') ? format('https://{0}/',reference(name_deploymentName).outputs.adminConsoleEndpoint): '' -output adminServerT3LBUrl string = length(lbSvcValues) > 0 && (reference(name_deploymentName).outputs.adminServerT3Endpoint != 'null') ? reference(name_deploymentName).outputs.adminServerT3Endpoint: '' -output adminRemoteUrl string = (!enableCustomSSL) && length(lbSvcValues) > 0 && (reference(name_deploymentName).outputs.adminRemoteEndpoint != 'null') ? format('http://{0}',reference(name_deploymentName).outputs.adminRemoteEndpoint): '' -output adminRemoteSecuredUrl string = enableCustomSSL && length(lbSvcValues) > 0 && (reference(name_deploymentName).outputs.adminRemoteEndpoint != 'null') ? format('https://{0}',reference(name_deploymentName).outputs.adminRemoteEndpoint): '' -output clusterLBUrl string = (!enableCustomSSL) && length(lbSvcValues) > 0 && (reference(name_deploymentName).outputs.clusterEndpoint != 'null') ? format('https://{0}/',reference(name_deploymentName).outputs.clusterEndpoint): '' -output clusterLBSecuredUrl string = enableCustomSSL && length(lbSvcValues) > 0 && (reference(name_deploymentName).outputs.clusterEndpoint != 'null') ? format('http://{0}/',reference(name_deploymentName).outputs.clusterEndpoint): '' -output clusterT3LBUrl string = length(lbSvcValues) > 0 && (reference(name_deploymentName).outputs.clusterT3Endpoint != 'null') ? reference(name_deploymentName).outputs.clusterT3Endpoint: '' - +output adminConsoleLBEndpoint string = (!enableCustomSSL) && length(lbSvcValues) > 0 && (deploymentScript.properties.outputs.adminConsoleEndpoint != 'null') ? format('http://{0}/', deploymentScript.properties.outputs.adminConsoleEndpoint) : '' +output adminConsoleLBSecuredEndpoint string = enableCustomSSL && length(lbSvcValues) > 0 && (deploymentScript.properties.outputs.adminConsoleEndpoint != 'null') ? format('https://{0}/', deploymentScript.properties.outputs.adminConsoleEndpoint) : '' +output adminServerT3LBEndpoint string = length(lbSvcValues) > 0 && (deploymentScript.properties.outputs.adminServerT3Endpoint != 'null') ? deploymentScript.properties.outputs.adminServerT3Endpoint : '' +output adminRemoteEndpoint string = (!enableCustomSSL) && length(lbSvcValues) > 0 && (deploymentScript.properties.outputs.adminRemoteEndpoint != 'null') ? format('http://{0}', deploymentScript.properties.outputs.adminRemoteEndpoint) : '' +output adminRemoteSecuredEndpoint string = enableCustomSSL && length(lbSvcValues) > 0 && (deploymentScript.properties.outputs.adminRemoteEndpoint != 'null') ? format('https://{0}', deploymentScript.properties.outputs.adminRemoteEndpoint) : '' +output clusterLBEndpoint string = (!enableCustomSSL) && length(lbSvcValues) > 0 && (deploymentScript.properties.outputs.clusterEndpoint != 'null') ? format('http://{0}/', deploymentScript.properties.outputs.clusterEndpoint) : '' +output clusterLBSecuredEndpoint string = enableCustomSSL && length(lbSvcValues) > 0 && (deploymentScript.properties.outputs.clusterEndpoint != 'null') ? format('https://{0}/', deploymentScript.properties.outputs.clusterEndpoint) : '' +output clusterT3LBEndpoint string = length(lbSvcValues) > 0 && (deploymentScript.properties.outputs.clusterT3Endpoint != 'null') ? deploymentScript.properties.outputs.clusterT3Endpoint : '' diff --git a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-create-wls-cluster.bicep b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-create-wls-cluster.bicep index 6ae022f00..4b198a7f8 100644 --- a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-create-wls-cluster.bicep +++ b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-create-wls-cluster.bicep @@ -1,36 +1,51 @@ // Copyright (c) 2021, Oracle Corporation and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -param _artifactsLocation string +param _artifactsLocation string = deployment().properties.templateLink.uri @secure() param _artifactsLocationSasToken string = '' +param _globalResourceNameSuffix string +param aksAgentPoolName string = '' param aksClusterRGName string = '' param aksClusterName string = '' param acrName string = '' +param acrResourceGroupName string = '' param appPackageUrls array = [] param appReplicas int = 2 +param azCliVersion string = '' +param cpuPlatform string = '' +param databaseType string = 'oracle' +param dbDriverLibrariesUrls array = [] param enableCustomSSL bool = false param enableAdminT3Tunneling bool = false param enableClusterT3Tunneling bool = false +param enablePswlessConnection bool = false param enablePV bool = false -param identity object -param location string = 'eastus' +param fileShareName string +param identity object = {} +param isSSOSupportEntitled bool +param location string param managedServerPrefix string = 'managed-server' @secure() param ocrSSOPSW string param ocrSSOUser string param storageAccountName string = 'null' +@description('${label.tagsLabel}') +param tagsByResource object param t3ChannelAdminPort int = 7005 param t3ChannelClusterPort int = 8011 param utcValue string = utcNow() +param userProvidedImagePath string = 'null' +param useOracleImage bool = true @secure() param wdtRuntimePassword string param wlsClusterSize int = 5 param wlsCPU string = '200m' param wlsDomainName string = 'domain1' param wlsDomainUID string = 'sample-domain1' -param wlsIdentityKeyStoreData string ='null' +@secure() +param wlsIdentityKeyStoreData string =newGuid() @secure() param wlsIdentityKeyStorePassphrase string = newGuid() @allowed([ @@ -43,10 +58,12 @@ param wlsJavaOption string = 'null' param wlsMemory string = '1.5Gi' @secure() param wlsPassword string -param wlsPrivateKeyAlias string ='contoso' +@secure() +param wlsPrivateKeyAlias string =newGuid() @secure() param wlsPrivateKeyPassPhrase string = newGuid() -param wlsTrustKeyStoreData string = 'null' +@secure() +param wlsTrustKeyStoreData string = newGuid() @secure() param wlsTrustKeyStorePassPhrase string = newGuid() @allowed([ @@ -56,10 +73,8 @@ param wlsTrustKeyStorePassPhrase string = newGuid() param wlsTrustKeyStoreType string = 'PKCS12' param wlsUserName string = 'weblogic' -var const_arguments = '${ocrSSOUser} ${ocrSSOPSW} ${aksClusterRGName} ${aksClusterName} ${wlsImageTag} ${acrName} ${wlsDomainName} ${wlsDomainUID} ${wlsUserName} ${wlsPassword} ${wdtRuntimePassword} ${wlsCPU} ${wlsMemory} ${managedServerPrefix} ${appReplicas} ${string(appPackageUrls)} ${resourceGroup().name} ${const_scriptLocation} ${storageAccountName} ${wlsClusterSize} ${enableCustomSSL} ${wlsIdentityKeyStoreData} ${wlsIdentityKeyStorePassphrase} ${wlsIdentityKeyStoreType} ${wlsPrivateKeyAlias} ${wlsPrivateKeyPassPhrase} ${wlsTrustKeyStoreData} ${wlsTrustKeyStorePassPhrase} ${wlsTrustKeyStoreType} ${enablePV} ${enableAdminT3Tunneling} ${enableClusterT3Tunneling} ${t3ChannelAdminPort} ${t3ChannelClusterPort} "${wlsJavaOption}"' var const_buildDockerImageScript='createVMAndBuildImage.sh' var const_commonScript = 'common.sh' -var const_invokeSetUpDomainScript = 'invokeSetupWLSDomain.sh' var const_pvTempalte = 'pv.yaml.template' var const_pvcTempalte = 'pvc.yaml.template' var const_scriptLocation = uri(_artifactsLocation, 'scripts/') @@ -68,17 +83,206 @@ var const_setUpDomainScript = 'setupWLSDomain.sh' var const_updateDomainConfigScript= 'updateDomainConfig.sh' var const_utilityScript= 'utility.sh' -resource deploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { - name: 'ds-wls-cluster-creation' +resource deploymentScript 'Microsoft.Resources/deploymentScripts@${azure.apiVersionForDeploymentScript}' = { + name: 'ds-wls-cluster-creation-${_globalResourceNameSuffix}' location: location kind: 'AzureCLI' identity: identity + tags: tagsByResource['${identifier.deploymentScripts}'] properties: { - azCliVersion: '2.15.0' - arguments: const_arguments - primaryScriptUri: uri(const_scriptLocation, '${const_invokeSetUpDomainScript}${_artifactsLocationSasToken}') + azCliVersion: azCliVersion + environmentVariables: [ + { + name: 'ACR_NAME' + value: acrName + } + { + name: 'ACR_RESOURCEGROUP_NAME' + value: acrResourceGroupName + } + { + name: 'AKS_CLUSTER_NAME' + value: aksClusterName + } + { + name: 'AKS_NODE_POOL_NAME' + value: aksAgentPoolName + } + { + name: 'AKS_CLUSTER_LOCATION' + value: location + } + { + name: 'AKS_CLUSTER_RESOURCEGROUP_NAME' + value: aksClusterRGName + } + { + name: 'CPU_PLATFORM' + value: cpuPlatform + } + { + name: 'CURRENT_RESOURCEGROUP_NAME' + value: resourceGroup().name + } + { + name: 'DB_TYPE' + value: databaseType + } + { + name: 'ENABLE_ADMIN_CUSTOM_T3' + value: string(enableAdminT3Tunneling) + } + { + name: 'ENABLE_CLUSTER_CUSTOM_T3' + value: string(enableClusterT3Tunneling) + } + { + name: 'ENABLE_CUSTOM_SSL' + value: string(enableCustomSSL) + } + { + name: 'ENABLE_SHIBBOLETHLESS_DB_CONNECTION' + value: string(enablePswlessConnection) + } + { + name: 'ENABLE_PV' + value: string(enablePV) + } + { + name: 'FILE_SHARE_NAME' + value: fileShareName + } + { + name: 'ORACLE_ACCOUNT_NAME' + value: ocrSSOUser + } + { + name: 'ORACLE_ACCOUNT_SHIBBOLETH' + secureValue: ocrSSOPSW + } + { + name: 'ORACLE_ACCOUNT_ENTITLED' + value: string(isSSOSupportEntitled) + } + { + name: 'SCRIPT_LOCATION' + value: const_scriptLocation + } + { + name: 'STORAGE_ACCOUNT_NAME' + value: storageAccountName + } + { + name: 'TAG_VM' + value: string(tagsByResource['${identifier.virtualMachines}']) + } + { + name: 'URL_3RD_DATASOURCE' + value: string(dbDriverLibrariesUrls) + } + { + name: 'USE_ORACLE_IMAGE' + value: string(useOracleImage) + } + { + name: 'USER_PROVIDED_IMAGE_PATH' + value: userProvidedImagePath + } + { + name: 'WLS_ADMIN_SHIBBOLETH' + secureValue: wlsPassword + } + { + name: 'WLS_ADMIN_USER_NAME' + secureValue: wlsUserName + } + { + name: 'WLS_APP_PACKAGE_URLS' + value: base64(string(appPackageUrls)) + } + { + name: 'WLS_APP_REPLICAS' + value: string(appReplicas) + } + { + name: 'WLS_CLUSTER_SIZE' + value: string(wlsClusterSize) + } + { + name: 'WLS_DOMAIN_NAME' + value: wlsDomainName + } + { + name: 'WLS_DOMAIN_UID' + value: wlsDomainUID + } + { + name: 'WLS_IMAGE_TAG' + value: wlsImageTag + } + { + name: 'WLS_JAVA_OPTIONS' + value: wlsJavaOption + } + { + name: 'WLS_MANAGED_SERVER_PREFIX' + value: managedServerPrefix + } + { + name: 'WLS_RESOURCE_REQUEST_CPU' + value: wlsCPU + } + { + name: 'WLS_RESOURCE_REQUEST_MEMORY' + value: wlsMemory + } + { + name: 'WLS_SSL_IDENTITY_DATA' + secureValue: wlsIdentityKeyStoreData + } + { + name: 'WLS_SSL_IDENTITY_SHIBBOLETH' + secureValue: wlsIdentityKeyStorePassphrase + } + { + name: 'WLS_SSL_IDENTITY_TYPE' + value: wlsIdentityKeyStoreType + } + { + name: 'WLS_SSL_TRUST_DATA' + secureValue: wlsTrustKeyStoreData + } + { + name: 'WLS_SSL_TRUST_SHIBBOLETH' + secureValue: wlsTrustKeyStorePassPhrase + } + { + name: 'WLS_SSL_TRUST_TYPE' + value: wlsTrustKeyStoreType + } + { + name: 'WLS_SSL_PRIVATE_KEY_ALIAS' + secureValue: wlsPrivateKeyAlias + } + { + name: 'WLS_SSL_PRIVATE_KEY_SHIBBOLETH' + secureValue: wlsPrivateKeyPassPhrase + } + { + name: 'WLS_T3_ADMIN_PORT' + value: string(t3ChannelAdminPort) + } + { + name: 'WLS_T3_CLUSTER_PORT' + value: string(t3ChannelClusterPort) + } + { + name: 'WLS_WDT_RUNTIME_PSW' + secureValue: wdtRuntimePassword + } + ] + primaryScriptUri: uri(const_scriptLocation, '${const_setUpDomainScript}${_artifactsLocationSasToken}') supportingScriptUris: [ - uri(const_scriptLocation, '${const_setUpDomainScript}${_artifactsLocationSasToken}') uri(const_scriptLocation, '${const_genDomainConfigScript}${_artifactsLocationSasToken}') uri(const_scriptLocation, '${const_utilityScript}${_artifactsLocationSasToken}') uri(const_scriptLocation, '${const_pvTempalte}${_artifactsLocationSasToken}') diff --git a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-datasource-connection.bicep b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-datasource-connection.bicep index b647a4bd6..301d0c399 100644 --- a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-datasource-connection.bicep +++ b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-datasource-connection.bicep @@ -1,19 +1,29 @@ // Copyright (c) 2021, Oracle Corporation and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -param _artifactsLocation string +param _artifactsLocation string = deployment().properties.templateLink.uri @secure() param _artifactsLocationSasToken string = '' +param _globalResourceNameSuffix string param aksClusterName string param aksClusterRGName string param databaseType string = 'oracle' -param dbConfigurationType string +param azCliVersion string = '' +param dbConfigurationType string = 'createOrUpdate' +param dbDriverName string = 'org.contoso.Driver' +param dbGlobalTranPro string = 'EmulateTwoPhaseCommit' +@secure() param dbPassword string = newGuid() +param dbTestTableName string = 'Null' param dbUser string param dsConnectionURL string -param identity object +param enablePswlessConnection bool = false +param identity object = {} param jdbcDataSourceName string +param location string +@description('${label.tagsLabel}') +param tagsByResource object param utcValue string = utcNow() param wlsDomainUID string = 'sample-domain1' @secure() @@ -21,27 +31,85 @@ param wlsPassword string @description('User name for WebLogic Administrator.') param wlsUserName string = 'weblogic' -var const_arguments = '${aksClusterRGName} ${aksClusterName} ${databaseType} ${dbPassword} ${dbUser} "${dsConnectionURL}" ${jdbcDataSourceName} ${wlsDomainUID} ${wlsUserName} ${wlsPassword} ${dbConfigurationType}' -var const_azcliVersion='2.15.0' var const_commonScript = 'common.sh' var const_datasourceScript='setupDBConnections.sh' var const_datasourceModelScript='genDatasourceModel.sh' var const_dbUtilityScript='dbUtility.sh' -var const_invokeSetupDBConnectionsScript='invokeSetupDBConnections.sh' var const_scriptLocation = uri(_artifactsLocation, 'scripts/') var const_utilityScript= 'utility.sh' -resource deploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { - name: 'ds-wls-db-connection' - location: resourceGroup().location +resource deploymentScript 'Microsoft.Resources/deploymentScripts@${azure.apiVersionForDeploymentScript}' = { + name: 'ds-wls-db-connection-${_globalResourceNameSuffix}' + location: location kind: 'AzureCLI' identity: identity + tags: tagsByResource['${identifier.deploymentScripts}'] properties: { - azCliVersion: const_azcliVersion - arguments: const_arguments - primaryScriptUri: uri(const_scriptLocation, '${const_invokeSetupDBConnectionsScript}${_artifactsLocationSasToken}') + azCliVersion: azCliVersion + environmentVariables: [ + { + name: 'AKS_RESOURCE_GROUP_NAME' + value: aksClusterRGName + } + { + name: 'AKS_NAME' + value: aksClusterName + } + { + name: 'DATABASE_TYPE' + value: databaseType + } + { + name: 'DB_CONFIGURATION_TYPE' + value: dbConfigurationType + } + { + name: 'DB_SHIBBOLETH' + secureValue: dbPassword + } + { + name: 'DB_USER' + value: dbUser + } + { + name: 'DB_CONNECTION_STRING' + value: dsConnectionURL + } + { + name: 'DB_DRIVER_NAME' + value: dbDriverName + } + { + name: 'ENABLE_SHIBBOLETHLESS_CONNECTION' + value: string(enablePswlessConnection) + } + { + name: 'GLOBAL_TRANSATION_PROTOCOL' + value: dbGlobalTranPro + } + { + name: 'JDBC_DATASOURCE_NAME' + value: jdbcDataSourceName + } + { + name: 'TEST_TABLE_NAME' + value: dbTestTableName + } + { + name: 'WLS_DOMAIN_UID' + value: wlsDomainUID + } + { + name: 'WLS_DOMAIN_USER' + value: wlsUserName + } + { + name: 'WLS_DOMAIN_SHIBBOLETH' + secureValue: wlsPassword + } + ] + primaryScriptUri: uri(const_scriptLocation, '${const_datasourceScript}${_artifactsLocationSasToken}') supportingScriptUris: [ - uri(const_scriptLocation, '${const_datasourceScript}${_artifactsLocationSasToken}') uri(const_scriptLocation, '${const_commonScript}${_artifactsLocationSasToken}') uri(const_scriptLocation, '${const_utilityScript}${_artifactsLocationSasToken}') uri(const_scriptLocation, '${const_dbUtilityScript}${_artifactsLocationSasToken}') diff --git a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-output-domain-configurations.bicep b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-output-domain-configurations.bicep new file mode 100644 index 000000000..d86fc1353 --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-output-domain-configurations.bicep @@ -0,0 +1,57 @@ +// Copyright (c) 2021, 2024 Oracle Corporation and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +param _globalResourceNameSuffix string +param aksClusterRGName string = '' +param aksClusterName string = '' +param azCliVersion string = '' +param identity object = {} +param location string +@description('${label.tagsLabel}') +param tagsByResource object +param utcValue string = utcNow() +param wlsClusterName string = 'cluster-1' +param wlsDomainUID string = 'sample-domain1' + +// To mitigate arm-ttk error: Unreferenced variable: $fxv#0 +var base64_common = loadFileAsBase64('../../../arm/scripts/common.sh') +var base64_queryDomainConfigurations = loadFileAsBase64('../../../arm/scripts/inline-scripts/queryDomainConfigurations.sh') +var base64_utility = loadFileAsBase64('../../../arm/scripts/utility.sh') + +resource deploymentScript 'Microsoft.Resources/deploymentScripts@${azure.apiVersionForDeploymentScript}' = { + name: 'ds-query-wls-configurations-${_globalResourceNameSuffix}' + location: location + kind: 'AzureCLI' + identity: identity + tags: tagsByResource['${identifier.deploymentScripts}'] + properties: { + azCliVersion: azCliVersion + environmentVariables: [ + { + name: 'AKS_CLUSTER_RESOURCEGROUP_NAME' + value: aksClusterRGName + } + { + name: 'AKS_CLUSTER_NAME' + value: aksClusterName + } + { + name: 'WLS_CLUSTER_NAME' + value: wlsClusterName + } + { + name: 'WLS_DOMAIN_UID' + value: wlsDomainUID + } + ] + scriptContent: format('{0}\r\n\r\n{1}\r\n\r\n{2}',base64ToString(base64_common), base64ToString(base64_utility), base64ToString(base64_queryDomainConfigurations)) + cleanupPreference: 'OnSuccess' + retentionInterval: 'P1D' + forceUpdateTag: utcValue + } +} + +output shellCmdtoOutputWlsDomainYaml string = format('echo -e {0} | base64 -d > domain.yaml', deploymentScript.properties.outputs.domainDeploymentYaml) +output shellCmdtoOutputWlsImageModelYaml string = format('echo -e {0} | base64 -d > model.yaml', deploymentScript.properties.outputs.wlsImageModelYaml) +output shellCmdtoOutputWlsImageProperties string = format('echo -e {0} | base64 -d > model.properties', deploymentScript.properties.outputs.wlsImageProperties) +output shellCmdtoOutputWlsVersions string = format('echo -e {0} | base64 -d > version.info', deploymentScript.properties.outputs.wlsVersionDetails) diff --git a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-query-storage-account.bicep b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-query-storage-account.bicep deleted file mode 100644 index e973be8ae..000000000 --- a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-query-storage-account.bicep +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2021, Oracle Corporation and/or its affiliates. -// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. - -param aksClusterName string = '' -param aksClusterRGName string = '' - -param identity object -param utcValue string = utcNow() - -var const_arguments = '${aksClusterRGName} ${aksClusterName}' -var const_azcliVersion='2.15.0' -var const_deploymentName='ds-query-storage-account' - -resource deploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { - name: const_deploymentName - location: resourceGroup().location - kind: 'AzureCLI' - identity: identity - properties: { - azCliVersion: const_azcliVersion - arguments: const_arguments - scriptContent: loadTextContent('../../../arm/scripts/queryStorageAccount.sh') - cleanupPreference: 'OnSuccess' - retentionInterval: 'P1D' - forceUpdateTag: utcValue - } -} - -output storageAccount string = string(reference(const_deploymentName).outputs.storageAccount) diff --git a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-validate-applications.bicep b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-validate-applications.bicep new file mode 100644 index 000000000..6cf54e5cc --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-validate-applications.bicep @@ -0,0 +1,70 @@ +// Copyright (c) 2021, Oracle Corporation and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +param _artifactsLocation string = deployment().properties.templateLink.uri +@secure() +param _artifactsLocationSasToken string = '' +param _globalResourceNameSuffix string + +param aksClusterRGName string = '' +param aksClusterName string = '' +param azCliVersion string = '' +param identity object = {} +param location string +@description('${label.tagsLabel}') +param tagsByResource object +param utcValue string = utcNow() +param wlsDomainUID string = 'sample-domain1' +@secure() +param wlsPassword string +@description('User name for WebLogic Administrator.') +param wlsUserName string = 'weblogic' + +var const_pyCheckAppStatusScript = 'checkApplicationStatus.py' +var const_scriptLocation = uri(_artifactsLocation, 'scripts/') +var const_validateAppScript= 'validateApplications.sh' +var const_utilityScript= 'utility.sh' +var const_commonScript= 'common.sh' + + +resource deploymentScript 'Microsoft.Resources/deploymentScripts@${azure.apiVersionForDeploymentScript}' = { + name: 'ds-wls-validate-applications-${_globalResourceNameSuffix}' + location: location + kind: 'AzureCLI' + identity: identity + tags: tagsByResource['${identifier.deploymentScripts}'] + properties: { + azCliVersion: azCliVersion + environmentVariables: [ + { + name: 'AKS_RESOURCE_GROUP_NAME' + value: aksClusterRGName + } + { + name: 'AKS_NAME' + value: aksClusterName + } + { + name: 'WLS_DOMAIN_UID' + value: wlsDomainUID + } + { + name: 'WLS_DOMAIN_USER' + value: wlsUserName + } + { + name: 'WLS_DOMAIN_SHIBBOLETH' + secureValue: wlsPassword + } + ] + primaryScriptUri: uri(const_scriptLocation, '${const_validateAppScript}${_artifactsLocationSasToken}') + supportingScriptUris: [ + uri(const_scriptLocation, '${const_commonScript}${_artifactsLocationSasToken}') + uri(const_scriptLocation, '${const_utilityScript}${_artifactsLocationSasToken}') + uri(const_scriptLocation, '${const_pyCheckAppStatusScript}${_artifactsLocationSasToken}') + ] + cleanupPreference: 'OnSuccess' + retentionInterval: 'P1D' + forceUpdateTag: utcValue + } +} diff --git a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-validate-parameters.bicep b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-validate-parameters.bicep new file mode 100644 index 000000000..ee3ea5328 --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds-validate-parameters.bicep @@ -0,0 +1,184 @@ +// Copyright (c) 2021, Oracle Corporation and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +param _globalResourceNameSuffix string +param acrName string +param acrResourceGroupName string +param aksAgentPoolNodeCount int +param aksAgentPoolVMSize string = '' +param aksClusterRGName string +param aksClusterName string +param aksVersion string = 'default' +param appGatewayCertificateOption string +@secure() +param appGatewaySSLCertData string +@secure() +param appGatewaySSLCertPassword string +param appReplicas int +param azCliVersion string = '' +param createAKSCluster bool +param createDNSZone bool +param dnszoneName string +param dnszoneRGName string +param enableAppGWIngress bool +param enableCustomSSL bool +param enableDNSConfiguration bool +param identity object = {} +param isSSOSupportEntitled bool +param location string +@secure() +param ocrSSOPSW string +param ocrSSOUser string +@secure() +param sslUploadedCustomIdentityKeyStoreData string +@secure() +param sslUploadedCustomIdentityKeyStorePassphrase string +param sslUploadedCustomIdentityKeyStoreType string +@secure() +param sslUploadedCustomTrustKeyStoreData string +@secure() +param sslUploadedCustomTrustKeyStorePassPhrase string +param sslUploadedCustomTrustKeyStoreType string +@secure() +param sslUploadedPrivateKeyAlias string +@secure() +param sslUploadedPrivateKeyPassPhrase string +@description('${label.tagsLabel}') +param tagsByResource object +param useAksWellTestedVersion bool = true +param userProvidedAcr string +param userProvidedAcrRgName string +param userProvidedImagePath string +param useOracleImage bool +param vnetForApplicationGateway object +param utcValue string = utcNow() +param wlsImageTag string + +// To mitigate arm-ttk error: Unreferenced variable: $fxv#0 +var base64_common = loadFileAsBase64('../../../arm/scripts/common.sh') +var base64_utility = loadFileAsBase64('../../../arm/scripts/utility.sh') +var base64_validateParameters = loadFileAsBase64('../../../arm/scripts/inline-scripts/validateParameters.sh') +var const_arguments = '${location} ${createAKSCluster} ${aksAgentPoolVMSize} ${aksAgentPoolNodeCount} ${useOracleImage} ${wlsImageTag} ${userProvidedImagePath} ${enableCustomSSL} ${appGatewayCertificateOption} ${enableAppGWIngress} ${const_checkDNSZone}' +var const_checkDNSZone = enableDNSConfiguration && !createDNSZone +var const_deploymentName = 'ds-validate-parameters-and-fail-fast-${_globalResourceNameSuffix}' + +resource deploymentScript 'Microsoft.Resources/deploymentScripts@${azure.apiVersionForDeploymentScript}' = { + name: const_deploymentName + location: location + kind: 'AzureCLI' + identity: identity + tags: tagsByResource['${identifier.deploymentScripts}'] + properties: { + azCliVersion: azCliVersion + arguments: const_arguments + environmentVariables: [ + { + name: 'ORACLE_ACCOUNT_NAME' + value: ocrSSOUser + } + { + name: 'ORACLE_ACCOUNT_SHIBBOLETH' + secureValue: ocrSSOPSW + } + { + name: 'ORACLE_ACCOUNT_ENTITLED' + value: string(isSSOSupportEntitled) + } + { + name: 'ACR_NAME' + value: acrName + } + { + name: 'ACR_RESOURCE_GROUP' + value: acrResourceGroupName + } + { + name: 'ACR_NAME_FOR_USER_PROVIDED_IMAGE' + value: userProvidedAcr + } + { + name: 'ACR_RG_NAME_FOR_USER_PROVIDED_IMAGE' + value: userProvidedAcrRgName + } + { + name: 'AKS_CLUSTER_NAME' + value: aksClusterName + } + { + name: 'AKS_CLUSTER_RESOURCEGROUP_NAME' + value: aksClusterRGName + } + { + name: 'AKS_VERSION' + value: aksVersion + } + { + name: 'APP_REPLICAS' + value: appReplicas + } + { + name: 'WLS_SSL_IDENTITY_DATA' + secureValue: sslUploadedCustomIdentityKeyStoreData + } + { + name: 'WLS_SSL_IDENTITY_SHIBBOLETH' + secureValue: sslUploadedCustomIdentityKeyStorePassphrase + } + { + name: 'WLS_SSL_IDENTITY_TYPE' + value: sslUploadedCustomIdentityKeyStoreType + } + { + name: 'WLS_SSL_TRUST_DATA' + secureValue: sslUploadedCustomTrustKeyStoreData + } + { + name: 'WLS_SSL_TRUST_SHIBBOLETH' + secureValue: sslUploadedCustomTrustKeyStorePassPhrase + } + { + name: 'WLS_SSL_TRUST_TYPE' + value: sslUploadedCustomTrustKeyStoreType + } + { + name: 'WLS_SSL_PRIVATE_KEY_ALIAS' + secureValue: sslUploadedPrivateKeyAlias + } + { + name: 'WLS_SSL_PRIVATE_KEY_SHIBBOLETH' + secureValue: sslUploadedPrivateKeyPassPhrase + } + { + name: 'APPLICATION_GATEWAY_SSL_FRONTEND_CERT_DATA' + value: appGatewaySSLCertData + } + { + name: 'APPLICATION_GATEWAY_SSL_FRONTEND_CERT_SHIBBOLETH' + value: appGatewaySSLCertPassword + } + { + name: 'DNS_ZONE_NAME' + value: dnszoneName + } + { + name: 'DNS_ZONE_RESOURCEGROUP_NAME' + value: dnszoneRGName + } + { + name: 'USE_AKS_WELL_TESTED_VERSION' + value: string(useAksWellTestedVersion) + } + { + name: 'VNET_FOR_APPLICATIONGATEWAY' + value: string(vnetForApplicationGateway) + } + ] + scriptContent: format('{0}\r\n\r\n{1}\r\n\r\n{2}', base64ToString(base64_common), base64ToString(base64_utility), base64ToString(base64_validateParameters)) + cleanupPreference: 'OnSuccess' + retentionInterval: 'P1D' + forceUpdateTag: utcValue + } +} + +output aksVersion string = deploymentScript.properties.outputs.aksVersion +output aksAgentAvailabilityZones array = json(deploymentScript.properties.outputs.agentAvailabilityZones) diff --git a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_enable_hpa.bicep b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_enable_hpa.bicep new file mode 100644 index 000000000..ec3571b0f --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_enable_hpa.bicep @@ -0,0 +1,71 @@ +// Copyright (c) 2024, Oracle Corporation and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +param _globalResourceNameSuffix string +param aksClusterName string +param aksClusterRGName string +param azCliVersion string +@allowed([ + 'cpu' + 'memory' +]) +param hpaScaleType string = 'cpu' +param identity object = {} +param location string +@description('${label.tagsLabel}') +param tagsByResource object +param utcValue string = utcNow() +param utilizationPercentage int +param wlsClusterSize int +param wlsNamespace string + +// To mitigate arm-ttk error: Unreferenced variable: $fxv#0 +var base64_common = loadFileAsBase64('../../../arm/scripts/common.sh') +var base64_enableHpa = loadFileAsBase64('../../../arm/scripts/inline-scripts/enableHpa.sh') +var base64_utility = loadFileAsBase64('../../../arm/scripts/utility.sh') +var const_deploymentName='ds-enable-hpa-${_globalResourceNameSuffix}' + +resource deploymentScript 'Microsoft.Resources/deploymentScripts@${azure.apiVersionForDeploymentScript}' = { + name: const_deploymentName + location: location + kind: 'AzureCLI' + identity: identity + tags: tagsByResource['${identifier.deploymentScripts}'] + properties: { + azCliVersion: azCliVersion + scriptContent: format('{0}\r\n\r\n{1}\r\n\r\n{2}',base64ToString(base64_common), base64ToString(base64_utility), base64ToString(base64_enableHpa)) + environmentVariables: [ + { + name: 'AKS_CLUSTER_RG_NAME' + value: aksClusterRGName + } + { + name: 'AKS_CLUSTER_NAME' + value: aksClusterName + } + { + name: 'CURRENT_RG_NAME' + value: resourceGroup().name + } + { + name: 'HPA_SCALE_TYPE' + value: hpaScaleType + } + { + name: 'UTILIZATION_PERCENTAGE' + value: string(utilizationPercentage) + } + { + name: 'WLS_CLUSTER_SIZE' + value: string(wlsClusterSize) + } + { + name: 'WLS_NAMESPACE' + value: wlsNamespace + } + ] + cleanupPreference: 'OnSuccess' + retentionInterval: 'P1D' + forceUpdateTag: utcValue + } +} diff --git a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_enable_prometheus_metrics.bicep b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_enable_prometheus_metrics.bicep new file mode 100644 index 000000000..e9e29f633 --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_enable_prometheus_metrics.bicep @@ -0,0 +1,109 @@ +// Copyright (c) 2024, Oracle Corporation and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +param _globalResourceNameSuffix string +param aksClusterName string +param aksClusterRGName string +param amaName string +param azCliVersion string +param identity object = {} +param kedaUamiName string +param location string +@description('${label.tagsLabel}') +param tagsByResource object +param utcValue string = utcNow() +param wlsClusterSize int +param wlsDomainUID string +param wlsNamespace string +@secure() +param wlsPassword string +param wlsUserName string +param workspaceId string + +// To mitigate arm-ttk error: Unreferenced variable: $fxv#0 +var base64_common = loadFileAsBase64('../../../arm/scripts/common.sh') +var base64_enableHpa = loadFileAsBase64('../../../arm/scripts/inline-scripts/enablePrometheusMetrics.sh') +var base64_utility = loadFileAsBase64('../../../arm/scripts/utility.sh') +var const_deploymentName = 'ds-enable-promethues-metrics-${_globalResourceNameSuffix}' +var const_kedaNamespace= 'keda' +var const_kedaSa= 'keda-operator' + +resource deploymentScript 'Microsoft.Resources/deploymentScripts@${azure.apiVersionForDeploymentScript}' = { + name: const_deploymentName + location: location + kind: 'AzureCLI' + identity: identity + tags: tagsByResource['${identifier.deploymentScripts}'] + properties: { + azCliVersion: azCliVersion + scriptContent: format('{0}\r\n\r\n{1}\r\n\r\n{2}', base64ToString(base64_common), base64ToString(base64_utility), base64ToString(base64_enableHpa)) + environmentVariables: [ + { + name: 'AKS_CLUSTER_RG_NAME' + value: aksClusterRGName + } + { + name: 'AKS_CLUSTER_NAME' + value: aksClusterName + } + { + name: 'AMA_NAME' + value: amaName + } + { + name: 'AMA_WORKSPACE_ID' + value: workspaceId + } + { + name: 'CURRENT_RG_NAME' + value: resourceGroup().name + } + { + name: 'KEDA_NAMESPACE' + value: const_kedaNamespace + } + { + name: 'KEDA_UAMI_NAME' + value: kedaUamiName + } + { + name: 'KEDA_SERVICE_ACCOUNT_NAME' + value: const_kedaSa + } + { + name: 'WLS_CLUSTER_SIZE' + value: string(wlsClusterSize) + } + { + name: 'WLS_ADMIN_SHIBBOLETH' + value: wlsPassword + } + { + name: 'WLS_ADMIN_USERNAME' + value: wlsUserName + } + { + name: 'WLS_DOMAIN_UID' + value: wlsDomainUID + } + { + name: 'WLS_NAMESPACE' + value: wlsNamespace + } + { + name: 'LOCATION' + value: location + } + { + name: 'SUBSCRIPTION' + value: split(subscription().id, '/')[2] + } + ] + cleanupPreference: 'OnSuccess' + retentionInterval: 'P1D' + forceUpdateTag: utcValue + } +} + +output kedaScalerServerAddress string = deploymentScript.properties.outputs.kedaScalerServerAddress +output base64ofKedaScalerSample string = deploymentScript.properties.outputs.base64ofKedaScalerSample diff --git a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_ensure_available_agic.bicep b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_ensure_available_agic.bicep new file mode 100644 index 000000000..e42042a66 --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_ensure_available_agic.bicep @@ -0,0 +1,48 @@ +// Copyright (c) 2022, Oracle Corporation and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +param aksClusterName string +param aksClusterRGName string +param appgwName string = 'appgw-contoso' +param azCliVersion string = '' +param identity object = {} +param location string +param utcValue string = utcNow() + +// To mitigate arm-ttk error: Unreferenced variable: $fxv#0 +var base64_common = loadFileAsBase64('../../../arm/scripts/common.sh') +var base64_enableAgic = loadFileAsBase64('../../../arm/scripts/inline-scripts/enableAgic.sh') +var base64_utility = loadFileAsBase64('../../../arm/scripts/utility.sh') +var const_deploymentName='ds-validate-agic-${uniqueString(utcValue)}' + +resource deploymentScript 'Microsoft.Resources/deploymentScripts@${azure.apiVersionForDeploymentScript}' = { + name: const_deploymentName + location: location + kind: 'AzureCLI' + identity: identity + properties: { + azCliVersion: azCliVersion + scriptContent: format('{0}\r\n\r\n{1}\r\n\r\n{2}',base64ToString(base64_common), base64ToString(base64_utility), base64ToString(base64_enableAgic)) + environmentVariables: [ + { + name: 'AKS_CLUSTER_RG_NAME' + value: aksClusterRGName + } + { + name: 'AKS_CLUSTER_NAME' + value: aksClusterName + } + { + name: 'APPGW_NAME' + value: appgwName + } + { + name: 'CURRENT_RG_NAME' + value: resourceGroup().name + } + ] + cleanupPreference: 'OnSuccess' + retentionInterval: 'P1D' + forceUpdateTag: utcValue + } +} diff --git a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_install_agic.bicep b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_install_agic.bicep new file mode 100644 index 000000000..fc355f699 --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_install_agic.bicep @@ -0,0 +1,52 @@ +// Copyright (c) 2024, Oracle Corporation and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +param _globalResourceNameSuffix string +param aksClusterName string +param aksClusterRGName string +param appgwName string = 'appgw-contoso' +param azCliVersion string = '' +param identity object = {} +param location string +@description('${label.tagsLabel}') +param tagsByResource object +param utcValue string = utcNow() + +// To mitigate arm-ttk error: Unreferenced variable: $fxv#0 +var base64_common = loadFileAsBase64('../../../arm/scripts/common.sh') +var base64_enableAgic = loadFileAsBase64('../../../arm/scripts/inline-scripts/enableAgic.sh') +var base64_utility = loadFileAsBase64('../../../arm/scripts/utility.sh') +var const_deploymentName='ds-install-agic-${_globalResourceNameSuffix}' + +resource deploymentScript 'Microsoft.Resources/deploymentScripts@${azure.apiVersionForDeploymentScript}' = { + name: const_deploymentName + location: location + kind: 'AzureCLI' + identity: identity + tags: tagsByResource['${identifier.deploymentScripts}'] + properties: { + azCliVersion: azCliVersion + scriptContent: format('{0}\r\n\r\n{1}\r\n\r\n{2}',base64ToString(base64_common), base64ToString(base64_utility), base64ToString(base64_enableAgic)) + environmentVariables: [ + { + name: 'AKS_CLUSTER_RG_NAME' + value: aksClusterRGName + } + { + name: 'AKS_CLUSTER_NAME' + value: aksClusterName + } + { + name: 'APPGW_NAME' + value: appgwName + } + { + name: 'CURRENT_RG_NAME' + value: resourceGroup().name + } + ] + cleanupPreference: 'OnSuccess' + retentionInterval: 'P1D' + forceUpdateTag: utcValue + } +} diff --git a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_query_available_private_ip_from_subnet.bicep b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_query_available_private_ip_from_subnet.bicep new file mode 100644 index 000000000..ea3ad9025 --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_query_available_private_ip_from_subnet.bicep @@ -0,0 +1,44 @@ +// Copyright (c) 2022, Oracle Corporation and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +param azCliVersion string = '' +param subnetId string = '/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/resourcegroupname/providers/Microsoft.Network/virtualNetworks/vnetname/subnets/subnetname' +param knownIP string = '10.0.0.1' + +param identity object = {} +param location string +@description('${label.tagsLabel}') +param tagsByResource object +param utcValue string = utcNow() + +// To mitigate arm-ttk error: Unreferenced variable: $fxv#0 +var base64_common = loadFileAsBase64('../../../arm/scripts/common.sh') +var base64_queryPrivateIPForAppGateway = loadFileAsBase64('../../../arm/scripts/inline-scripts/queryPrivateIPForAppGateway.sh') +var const_deploymentName = 'ds-query-private-ip-${uniqueString(utcValue)}' + +resource deploymentScript 'Microsoft.Resources/deploymentScripts@${azure.apiVersionForDeploymentScript}' = { + name: const_deploymentName + location: location + kind: 'AzureCLI' + identity: identity + tags: tagsByResource['${identifier.deploymentScripts}'] + properties: { + azCliVersion: azCliVersion + scriptContent: format('{0}\r\n\r\n{1}', base64ToString(base64_common), base64ToString(base64_queryPrivateIPForAppGateway)) + environmentVariables: [ + { + name: 'SUBNET_ID' + value: subnetId + } + { + name: 'KNOWN_IP' + value: knownIP + } + ] + cleanupPreference: 'OnSuccess' + retentionInterval: 'P1D' + forceUpdateTag: utcValue + } +} + +output privateIP string = string(deploymentScript.properties.outputs.privateIP) diff --git a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_update-applications.bicep b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_update-applications.bicep index 6e83cc448..edb36e12c 100644 --- a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_update-applications.bicep +++ b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_update-applications.bicep @@ -1,7 +1,7 @@ // Copyright (c) 2021, Oracle Corporation and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -param _artifactsLocation string +param _artifactsLocation string = deployment().properties.templateLink.uri @secure() param _artifactsLocationSasToken string = '' @@ -13,7 +13,10 @@ param appPackageFromStorageBlob object = { storageAccountName: 'stg-contoso' containerName: 'container-contoso' } -param identity object +param azCliVersion string = '' +param identity object = {} +param isSSOSupportEntitled bool +param location string @secure() param ocrSSOPSW string @@ -23,27 +26,91 @@ param utcValue string = utcNow() param wlsDomainName string = 'domain1' param wlsDomainUID string = 'sample-domain1' param wlsImageTag string = '12.2.1.4' +param userProvidedImagePath string = 'null' +param useOracleImage bool = true -var const_arguments = '${ocrSSOUser} ${ocrSSOPSW} ${aksClusterRGName} ${aksClusterName} ${wlsImageTag} ${acrName} ${wlsDomainName} ${wlsDomainUID} ${resourceGroup().name} ${string(appPackageUrls)} ${const_scriptLocation} ${appPackageFromStorageBlob.storageAccountName} ${appPackageFromStorageBlob.containerName} ' -var const_azcliVersion='2.15.0' var const_buildDockerImageScript='createVMAndBuildImage.sh' var const_commonScript = 'common.sh' -var const_invokeScript = 'invokeUpdateApplications.sh' var const_scriptLocation = uri(_artifactsLocation, 'scripts/') var const_updateAppScript= 'updateApplications.sh' var const_utilityScript= 'utility.sh' -resource deploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { - name: 'ds-wls-update-applications' - location: resourceGroup().location +resource deploymentScript 'Microsoft.Resources/deploymentScripts@${azure.apiVersionForDeploymentScript}' = { + name: 'ds-wls-update-applications-${uniqueString(utcValue)}' + location: location kind: 'AzureCLI' identity: identity properties: { - azCliVersion: const_azcliVersion - arguments: const_arguments - primaryScriptUri: uri(const_scriptLocation, '${const_invokeScript}${_artifactsLocationSasToken}') + azCliVersion: azCliVersion + environmentVariables: [ + { + name: 'ACR_NAME' + value: acrName + } + { + name: 'AKS_CLUSTER_NAME' + value: aksClusterName + } + { + name: 'AKS_CLUSTER_RESOURCEGROUP_NAME' + value: aksClusterRGName + } + { + name: 'CURRENT_RESOURCEGROUP_NAME' + value: resourceGroup().name + } + { + name: 'ORACLE_ACCOUNT_ENTITLED' + value: string(isSSOSupportEntitled) + } + { + name: 'ORACLE_ACCOUNT_NAME' + value: ocrSSOUser + } + { + name: 'ORACLE_ACCOUNT_SHIBBOLETH' + secureValue: ocrSSOPSW + } + { + name: 'STORAGE_ACCOUNT_NAME' + value: appPackageFromStorageBlob.storageAccountName + } + { + name: 'STORAGE_ACCOUNT_CONTAINER_NAME' + value: appPackageFromStorageBlob.containerName + } + { + name: 'SCRIPT_LOCATION' + value: const_scriptLocation + } + { + name: 'USE_ORACLE_IMAGE' + value: string(useOracleImage) + } + { + name: 'USER_PROVIDED_IMAGE_PATH' + value: userProvidedImagePath + } + { + name: 'WLS_APP_PACKAGE_URLS' + value: string(appPackageUrls) + } + { + name: 'WLS_DOMAIN_NAME' + value: wlsDomainName + } + { + name: 'WLS_DOMAIN_UID' + value: wlsDomainUID + } + { + name: 'WLS_IMAGE_TAG' + value: wlsImageTag + } + + ] + primaryScriptUri: uri(const_scriptLocation, '${const_updateAppScript}${_artifactsLocationSasToken}') supportingScriptUris: [ - uri(const_scriptLocation, '${const_updateAppScript}${_artifactsLocationSasToken}') uri(const_scriptLocation, '${const_commonScript}${_artifactsLocationSasToken}') uri(const_scriptLocation, '${const_utilityScript}${_artifactsLocationSasToken}') uri(const_scriptLocation, '${const_buildDockerImageScript}${_artifactsLocationSasToken}') @@ -54,4 +121,4 @@ resource deploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { } } -output image string = reference('ds-wls-update-applications').outputs.image +output image string = deploymentScript.properties.outputs.image diff --git a/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_validate_agic.bicep b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_validate_agic.bicep new file mode 100644 index 000000000..437ac0128 --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_deployment-scripts/_ds_validate_agic.bicep @@ -0,0 +1,47 @@ +// Copyright (c) 2024, Oracle Corporation and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +param _globalResourceNameSuffix string +param aksClusterName string +param aksClusterRGName string +param azCliVersion string = '' +param identity object = {} +param location string +@description('${label.tagsLabel}') +param tagsByResource object +param utcValue string = utcNow() + +// To mitigate arm-ttk error: Unreferenced variable: $fxv#0 +var base64_common = loadFileAsBase64('../../../arm/scripts/common.sh') +var base64_enableAgic = loadFileAsBase64('../../../arm/scripts/inline-scripts/validateAgic.sh') +var base64_utility = loadFileAsBase64('../../../arm/scripts/utility.sh') +var const_deploymentName='ds-validate-agic-${_globalResourceNameSuffix}' + +resource deploymentScript 'Microsoft.Resources/deploymentScripts@${azure.apiVersionForDeploymentScript}' = { + name: const_deploymentName + location: location + kind: 'AzureCLI' + identity: identity + tags: tagsByResource['${identifier.deploymentScripts}'] + properties: { + azCliVersion: azCliVersion + scriptContent: format('{0}\r\n\r\n{1}\r\n\r\n{2}',base64ToString(base64_common), base64ToString(base64_utility), base64ToString(base64_enableAgic)) + environmentVariables: [ + { + name: 'AKS_CLUSTER_RG_NAME' + value: aksClusterRGName + } + { + name: 'AKS_CLUSTER_NAME' + value: aksClusterName + } + { + name: 'CURRENT_RG_NAME' + value: resourceGroup().name + } + ] + cleanupPreference: 'OnSuccess' + retentionInterval: 'P1D' + forceUpdateTag: utcValue + } +} diff --git a/weblogic-azure-aks/src/main/bicep/modules/_enableAutoScaling.bicep b/weblogic-azure-aks/src/main/bicep/modules/_enableAutoScaling.bicep new file mode 100644 index 000000000..59d78778a --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_enableAutoScaling.bicep @@ -0,0 +1,127 @@ +/* + Copyright (c) 2024, Oracle and/or its affiliates. +Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +*/ + +param _globalResourceNameSuffix string +param _pidCPUUtilization string = '' +param _pidEnd string = '' +param _pidMemoryUtilization string = '' +param _pidStart string = '' +param _pidWme string = '' + +param aksClusterName string +param aksClusterRGName string +param azCliVersion string + +@allowed([ + 'cpu' + 'memory' +]) +param hpaScaleType string = 'cpu' +param identity object = {} +param location string +@description('${label.tagsLabel}') +param tagsByResource object +param useHpa bool +param utilizationPercentage int +param wlsClusterSize int +param wlsDomainUID string +@secure() +param wlsPassword string +param wlsUserName string + +var const_namespace = '${wlsDomainUID}-ns' + +module pidAutoScalingStart './_pids/_pid.bicep' = { + name: 'pid-auto-scaling-start' + params: { + name: _pidStart + } +} + +module pidCpuUtilization './_pids/_pid.bicep' = if(useHpa && hpaScaleType == 'cpu') { + name: 'pid-auto-scaling-based-on-cpu-utilization' + params: { + name: _pidCPUUtilization + } + dependsOn: [ + pidAutoScalingStart + ] +} + +module pidMemoryUtilization './_pids/_pid.bicep' = if(useHpa && hpaScaleType == 'memory') { + name: 'pid-auto-scaling-based-on-memory-utilization' + params: { + name: _pidMemoryUtilization + } + dependsOn: [ + pidAutoScalingStart + ] +} + +module pidWme './_pids/_pid.bicep' = if(!useHpa) { + name: 'pid-auto-scaling-based-on-java-metrics' + params: { + name: _pidWme + } + dependsOn: [ + pidAutoScalingStart + ] +} + +module hapDeployment '_deployment-scripts/_ds_enable_hpa.bicep' = if(useHpa) { + name: 'hpa-deployment' + params: { + _globalResourceNameSuffix: _globalResourceNameSuffix + aksClusterName: aksClusterName + aksClusterRGName: aksClusterRGName + azCliVersion: azCliVersion + hpaScaleType: hpaScaleType + identity: identity + location: location + tagsByResource: tagsByResource + utilizationPercentage: utilizationPercentage + wlsClusterSize: wlsClusterSize + wlsNamespace: const_namespace + } + dependsOn: [ + pidAutoScalingStart + ] +} + +module promethuesKedaDeployment '_enablePromethuesKeda.bicep' = if (!useHpa) { + name: 'promethues-keda-weblogic-monitoring-exporter-deployment' + params: { + _globalResourceNameSuffix: _globalResourceNameSuffix + aksClusterName: aksClusterName + aksClusterRGName: aksClusterRGName + azCliVersion: azCliVersion + identity: identity + location: location + tagsByResource: tagsByResource + wlsClusterSize: wlsClusterSize + wlsDomainUID: wlsDomainUID + wlsPassword: wlsPassword + wlsUserName: wlsUserName + } + dependsOn: [ + pidAutoScalingStart + ] +} + + + +module pidAutoScalingEnd './_pids/_pid.bicep' = { + name: 'pid-auto-scaling-end' + params: { + name: _pidEnd + } + dependsOn: [ + hapDeployment + promethuesKedaDeployment + ] +} + +output kedaScalerServerAddress string = useHpa ? '' : promethuesKedaDeployment.outputs.kedaScalerServerAddress +output base64ofKedaScalerSample string = useHpa ? '' : promethuesKedaDeployment.outputs.base64ofKedaScalerSample diff --git a/weblogic-azure-aks/src/main/bicep/modules/_enablePromethuesKeda.bicep b/weblogic-azure-aks/src/main/bicep/modules/_enablePromethuesKeda.bicep new file mode 100644 index 000000000..fc5aa1a2e --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_enablePromethuesKeda.bicep @@ -0,0 +1,87 @@ +/* + Copyright (c) 2024, Oracle and/or its affiliates. +Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +*/ +param _globalResourceNameSuffix string +param aksClusterName string +param aksClusterRGName string +param azCliVersion string +param identity object = {} +param location string +@description('${label.tagsLabel}') +param tagsByResource object +param utcValue string = utcNow() +param wlsClusterSize int +param wlsDomainUID string +@secure() +param wlsPassword string +param wlsUserName string + +var const_namespace = '${wlsDomainUID}-ns' +// https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles +var const_roleDefinitionIdOfMonitorDataReader = 'b24988ac-6180-42a0-ab88-20f7382dd24c' +var name_azureMonitorAccountName = 'ama${_globalResourceNameSuffix}' +var name_kedaUserDefinedManagedIdentity = 'kedauami${_globalResourceNameSuffix}' +var name_kedaMonitorDataReaderRoleAssignmentName = guid('${resourceGroup().id}${name_kedaUserDefinedManagedIdentity}${_globalResourceNameSuffix}') + +resource monitorAccount 'Microsoft.Monitor/accounts@${azure.apiVersionForMonitorAccount}' = { + name: name_azureMonitorAccountName + location: location + properties: {} + tags: tagsByResource['${identifier.accounts}'] +} + +// UAMI for KEDA +resource uamiForKeda 'Microsoft.ManagedIdentity/userAssignedIdentities@${azure.apiVersionForIdentity}' = { + name: name_kedaUserDefinedManagedIdentity + location: location + tags: tagsByResource['${identifier.userAssignedIdentities}'] +} + +// Get role resource id +resource monitorDataReaderResourceDefinition 'Microsoft.Authorization/roleDefinitions@${azure.apiVersionForRoleDefinitions}' existing = { + name: const_roleDefinitionIdOfMonitorDataReader +} + +// Assign Monitor Data Reader role we need the permission to read data. +resource kedaUamiRoleAssignment 'Microsoft.Authorization/roleAssignments@${azure.apiVersionForRoleAssignment}' = { + name: name_kedaMonitorDataReaderRoleAssignmentName + scope: monitorAccount + properties: { + description: 'Assign Monitor Data Reader role role to KEDA Identity ' + principalId: reference(uamiForKeda.id, '${azure.apiVersionForIdentity}', 'full').properties.principalId + principalType: 'ServicePrincipal' + roleDefinitionId: monitorDataReaderResourceDefinition.id + } + dependsOn: [ + monitorAccount + uamiForKeda + ] +} + +module azureMonitorIntegrationDeployment '_deployment-scripts/_ds_enable_prometheus_metrics.bicep' = { + name: 'azure-monitor-promethues-keda-deployment' + params: { + _globalResourceNameSuffix: _globalResourceNameSuffix + aksClusterName: aksClusterName + aksClusterRGName: aksClusterRGName + amaName: name_azureMonitorAccountName + azCliVersion: azCliVersion + identity: identity + kedaUamiName: name_kedaUserDefinedManagedIdentity + location: location + tagsByResource: tagsByResource + wlsClusterSize: wlsClusterSize + wlsDomainUID: wlsDomainUID + wlsNamespace: const_namespace + wlsPassword: wlsPassword + wlsUserName: wlsUserName + workspaceId: monitorAccount.id + } + dependsOn: [ + kedaUamiRoleAssignment + ] +} + +output kedaScalerServerAddress string = azureMonitorIntegrationDeployment.outputs.kedaScalerServerAddress +output base64ofKedaScalerSample string = format('echo -e {0} | base64 -d > scaler.yaml', azureMonitorIntegrationDeployment.outputs.base64ofKedaScalerSample) diff --git a/weblogic-azure-aks/src/main/bicep/modules/_globalUamiAndRoles.bicep b/weblogic-azure-aks/src/main/bicep/modules/_globalUamiAndRoles.bicep new file mode 100644 index 000000000..e5acfe269 --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_globalUamiAndRoles.bicep @@ -0,0 +1,33 @@ +/* + Copyright (c) 2021, Oracle and/or its affiliates. +Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +*/ + +param _globalResourceNameSuffix string +param location string +@description('${label.tagsLabel}') +param tagsByResource object +param name_deploymentScriptContributorRoleAssignmentName string = newGuid() + +// https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles +var const_roleDefinitionIdOfContributor = 'b24988ac-6180-42a0-ab88-20f7382dd24c' +var name_deploymentScriptUserDefinedManagedIdentity = 'wls-aks-deployment-script-user-defined-managed-itentity-${_globalResourceNameSuffix}' + +// UAMI for deployment script +resource uamiForDeploymentScript 'Microsoft.ManagedIdentity/userAssignedIdentities@${azure.apiVersionForIdentity}' = { + name: name_deploymentScriptUserDefinedManagedIdentity + location: location + tags: tagsByResource['${identifier.userAssignedIdentities}'] +} + +// Assign Contributor role in subscription scope, we need the permission to get/update resource cross resource group. +module deploymentScriptUAMICotibutorRoleAssignment '_rolesAssignment/_roleAssignmentinSubscription.bicep' = { + name: name_deploymentScriptContributorRoleAssignmentName + scope: subscription() + params: { + roleDefinitionId: const_roleDefinitionIdOfContributor + principalId: reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', name_deploymentScriptUserDefinedManagedIdentity)).principalId + } +} + +output uamiIdForDeploymentScript string = uamiForDeploymentScript.id diff --git a/weblogic-azure-aks/src/main/bicep/modules/_pids/_empty.bicep b/weblogic-azure-aks/src/main/bicep/modules/_pids/_empty.bicep index f30cdc641..98e4de354 100644 --- a/weblogic-azure-aks/src/main/bicep/modules/_pids/_empty.bicep +++ b/weblogic-azure-aks/src/main/bicep/modules/_pids/_empty.bicep @@ -8,3 +8,8 @@ * name: name * } */ + +// Workaround to arm-ttk complain: Parameters property must exist in the template +param name string = 'This is an empty deployment' + +output name string = name diff --git a/weblogic-azure-aks/src/main/bicep/modules/_pids/_pid-dev.bicep b/weblogic-azure-aks/src/main/bicep/modules/_pids/_pid-dev.bicep index 9f0a680e3..98c1e07f4 100644 --- a/weblogic-azure-aks/src/main/bicep/modules/_pids/_pid-dev.bicep +++ b/weblogic-azure-aks/src/main/bicep/modules/_pids/_pid-dev.bicep @@ -1,4 +1,4 @@ -// Copyright (c) 2021, Oracle Corporation and/or its affiliates. +// Copyright (c) 2021, 2024, Oracle Corporation and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. // Deployment for pids. @@ -12,10 +12,25 @@ module pidStart './_empty.bicep' = if (name != 'pid'){ output appgwEnd string = '38647ff6-ea8d-59e5-832d-b036a4d29c73' output appgwStart string = '8ba7beaa-96fd-576a-acd8-28f7a6efa83a' +output autoScalingEnd string = '074fd64c-184f-4bb9-b878-448cae164601' +output autoScalingStart string = 'f4e5974d-6531-4a34-a733-e7416258fe03' +output customCertForAppgw string = 'b16ba29f-fc8e-5059-8988-f17bef4a9c5c' +output cpuUtilization string = '22a34519-24ea-4864-b304-7e47aee4071b' output dbEnd string = 'ffab0a3f-90cb-585a-a7f9-ec0a62faeec1' output dbStart string = 'e64361eb-fea0-5f15-a313-c76daadbc648' +output dnsEnd string = '189306c7-39e2-5844-817d-01e883a4cf1e' +output dnsStart string = '8ae63711-9fa7-56b4-a4a0-236f3ccef542' +output enableWlsMonitoringExporter string = '960632d4-918a-47c4-a32e-61ab0d4c470a' +output lbEnd string = 'f76e2847-d5a1-52e7-9e52-fc8560f5d3e4' +output lbStart string = 'e2a8c8b2-9b58-52c6-9636-1834ff3976dc' output networkingEnd string = '39d32fcd-1d02-50b6-9455-4b767a8e769e' output networkingStart string = 'ed47756f-2475-56dd-b13a-26027749b6e1' +output memoryUtilization string = 'b9b57564-3603-4d27-8e0c-a853ef0d60b9' +output otherDb string = '551122ff-2fea-53a8-b7f4-6d6dae85af6a' +output pswlessDbEnd string = '7e7aaa5b-2251-55b5-8b3d-43d514738cf2' +output pswlessDbStart string = '089e9783-6707-54d0-ac8c-9b8d517914c5' +output sslEnd string = 'fd285d8c-8d24-5d4e-b9f9-81f252ebfc6d' +output sslStart string = 'eb67405c-3276-53bb-b1bc-db6dad811d71' output wlsAKSEnd string = '17328b4d-841f-57b5-a9c5-861ad48f9d0d' output wlsAKSStart string = 'c46a11b1-e8d2-5053-9741-45294b2e15c9' output wlsClusterAppEnd string = '18121d1c-4227-51ff-a9fa-ceb890d683e3' diff --git a/weblogic-azure-aks/src/main/bicep/modules/_pids/_pid.bicep b/weblogic-azure-aks/src/main/bicep/modules/_pids/_pid.bicep index ed81fb5b7..b86bae86f 100644 --- a/weblogic-azure-aks/src/main/bicep/modules/_pids/_pid.bicep +++ b/weblogic-azure-aks/src/main/bicep/modules/_pids/_pid.bicep @@ -1,4 +1,4 @@ -// Copyright (c) 2021, Oracle Corporation and/or its affiliates. +// Copyright (c) 2021, 2024, Oracle Corporation and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. // Deployment for pids. @@ -12,10 +12,25 @@ module pidStart './_empty.bicep' = if (name != 'pid'){ output appgwEnd string = '47ea43a0-95cf-52c7-aee8-7ee6106fc1bf' output appgwStart string = '01288010-2672-5831-a66b-7b8b45cace1b' +output autoScalingEnd string = 'fff261b8-f09f-4c46-b7b7-923c239f1da5' +output autoScalingStart string = '94fd65ac-bb13-475d-aba7-3352288777c2' +output customCertForAppgw string = 'b80f52c3-dddd-5286-915e-e4cc64be3093' +output cpuUtilization string = 'deb6b656-aa63-4014-a686-6a01e8f87fec' output dbEnd string = 'd7a9c78e-39d9-5a47-928d-8645ed86dafd' output dbStart string = '0cc86800-37f4-5191-9368-2953394309ec' +output dnsEnd string = '754e16bc-4d81-5343-b99b-7532abd6587d' +output dnsStart string = '64ae895c-feb3-529e-8435-5d2e49f94e09' +output enableWlsMonitoringExporter string = '5e607302-2e52-42c4-8f02-29db35e3ddf1' +output lbEnd string = 'ce664543-77bd-515a-832e-107e32f99da9' +output lbStart string = '44732bbc-04c4-5df7-a0c6-b9be9ec00ee6' output networkingEnd string = '2798165c-49fa-5701-b608-b80ed3986176' output networkingStart string = '0793308f-de9d-5f0d-92f9-d9fc4b413b8b' +output memoryUtilization string = 'd1c2d027-f030-4a18-8e74-d608dd10c6f3' +output otherDb string = 'fceccc86-531c-5e44-99fd-9f1250f8e409' +output pswlessDbEnd string = '972084b9-2b2d-5eb9-aa37-80448a77fbe1' +output pswlessDbStart string = '7190b263-7825-5ae3-bc56-7294df936d4a' +output sslEnd string = '6738fb2b-4383-520e-bf8a-b4e00162b692' +output sslStart string = '29953382-5f6a-5bcf-9453-0bb82475951c' output wlsAKSEnd string = '2571f846-2f66-5c22-9fe6-38ecea7889ac' output wlsAKSStart string = '3e6acde5-9a62-5488-9fd4-87c46f4105f4' output wlsClusterAppEnd string = 'e6e33240-e5db-52fc-9154-7fc7b3b8b508' diff --git a/weblogic-azure-aks/src/main/bicep/modules/_preDeployedAzureResources.bicep b/weblogic-azure-aks/src/main/bicep/modules/_preDeployedAzureResources.bicep new file mode 100644 index 000000000..0790d55a1 --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_preDeployedAzureResources.bicep @@ -0,0 +1,24 @@ +/* + Copyright (c) 2021, Oracle and/or its affiliates. +Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +*/ + +param acrName string = 'acr-contoso' +param acrResourceGroupName string = 'acr-contoso-rg' +param createNewAcr bool = false +@description('${label.tagsLabel}') +param tagsByResource object + +param location string + +module acrDeployment './_azure-resoruces/_acr.bicep' = if (createNewAcr) { + name: 'acr-deployment' + params: { + acrName: acrName + location: location + tagsByResource: tagsByResource + } +} + +output acrName string = createNewAcr ? acrDeployment.outputs.acrName : acrName +output acrResourceGroupName string = createNewAcr ? resourceGroup().name : acrResourceGroupName diff --git a/weblogic-azure-aks/src/main/bicep/modules/_rolesAssignment/_agicNetworkContributor.bicep b/weblogic-azure-aks/src/main/bicep/modules/_rolesAssignment/_agicNetworkContributor.bicep new file mode 100644 index 000000000..e2bc8bed0 --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_rolesAssignment/_agicNetworkContributor.bicep @@ -0,0 +1,31 @@ +/* + Copyright (c) 2021, 2024, Oracle and/or its affiliates. +Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +*/ + +param aksClusterName string +param aksClusterRGName string +param utcValue string = utcNow() + +var const_APIVersion = '2020-12-01' +var name_appGwContributorRoleAssignmentName = guid('${resourceGroup().id}${uniqueString(utcValue)}NetworkContributor') +// https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles +var const_roleDefinitionIdOfVnetContributor = '4d97b98b-1d4f-4787-a291-c67834d212e7' + +resource aksCluster 'Microsoft.ContainerService/managedClusters@${azure.apiVersionForManagedClusters}' existing = { + name: aksClusterName + scope: resourceGroup(aksClusterRGName) +} + +resource agicUamiRoleAssignment 'Microsoft.Authorization/roleAssignments@${azure.apiVersionForRoleAssignment}' = { + name: name_appGwContributorRoleAssignmentName + properties: { + description: 'Assign Network Contributor role to AGIC Identity ' + principalId: reference(aksCluster.id, const_APIVersion , 'Full').properties.addonProfiles.ingressApplicationGateway.identity.objectId + principalType: 'ServicePrincipal' + roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', const_roleDefinitionIdOfVnetContributor) + } + dependsOn: [ + aksCluster + ] +} diff --git a/weblogic-azure-aks/src/main/bicep/modules/_rolesAssignment/_agicRoleAssignment.bicep b/weblogic-azure-aks/src/main/bicep/modules/_rolesAssignment/_agicRoleAssignment.bicep new file mode 100644 index 000000000..85f56df12 --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_rolesAssignment/_agicRoleAssignment.bicep @@ -0,0 +1,31 @@ +/* + Copyright (c) 2021, Oracle and/or its affiliates. +Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +*/ + +param aksClusterName string +param aksClusterRGName string +param utcValue string = utcNow() + +var const_APIVersion = '2020-12-01' +var name_appGwContributorRoleAssignmentName = guid('${resourceGroup().id}${uniqueString(utcValue)}ForApplicationGateway') +// https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles +var const_roleDefinitionIdOfContributor = 'b24988ac-6180-42a0-ab88-20f7382dd24c' + +resource aksCluster 'Microsoft.ContainerService/managedClusters@${azure.apiVersionForManagedClusters}' existing = { + name: aksClusterName + scope: resourceGroup(aksClusterRGName) +} + +resource agicUamiRoleAssignment 'Microsoft.Authorization/roleAssignments@${azure.apiVersionForRoleAssignment}' = { + name: name_appGwContributorRoleAssignmentName + properties: { + description: 'Assign Resource Group Contributor role to User Assigned Managed Identity ' + principalId: reference(aksCluster.id, const_APIVersion , 'Full').properties.addonProfiles.ingressApplicationGateway.identity.objectId + principalType: 'ServicePrincipal' + roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', const_roleDefinitionIdOfContributor) + } + dependsOn: [ + aksCluster + ] +} diff --git a/weblogic-azure-aks/src/main/bicep/modules/_rolesAssignment/_aksClusterMioRoleOverDbIdentity.bicep b/weblogic-azure-aks/src/main/bicep/modules/_rolesAssignment/_aksClusterMioRoleOverDbIdentity.bicep new file mode 100644 index 000000000..514d47094 --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_rolesAssignment/_aksClusterMioRoleOverDbIdentity.bicep @@ -0,0 +1,34 @@ +/* + Copyright (c) 2021, Oracle and/or its affiliates. +Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +*/ + +param clusterIdentityPrincipalId string = '' +param dbIdentityName string = '' + +// https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles +var const_roleDefinitionIdOfManagedIdentityOperator = 'f1a07417-d97a-45cb-824c-7a7467783830' +var name_roleAssignmentName = guid('${subscription().id}${clusterIdentityPrincipalId}Role assignment in resource scope') + +resource dbIdentityResource 'Microsoft.ManagedIdentity/userAssignedIdentities@${azure.apiVersionForIdentity}' existing = { + name: dbIdentityName +} + +// Get role resource id +resource roleResourceDefinition 'Microsoft.Authorization/roleDefinitions@${azure.apiVersionForRoleDefinitions}' existing = { + name: const_roleDefinitionIdOfManagedIdentityOperator +} + +// Assign role +resource roleAssignment 'Microsoft.Authorization/roleAssignments@${azure.apiVersionForRoleAssignment}' = { + name: name_roleAssignmentName + scope: dbIdentityResource + properties: { + description: 'Assign Managed Identity Operator role to AKS Cluster over DB Identity ' + principalId: clusterIdentityPrincipalId + principalType: 'ServicePrincipal' + roleDefinitionId: roleResourceDefinition.id + } +} + +output roleId string = roleResourceDefinition.id diff --git a/weblogic-azure-aks/src/main/bicep/modules/_rolesAssignment/_roleAssignmentinRgScope.bicep b/weblogic-azure-aks/src/main/bicep/modules/_rolesAssignment/_roleAssignmentinRgScope.bicep new file mode 100644 index 000000000..f5b50c20d --- /dev/null +++ b/weblogic-azure-aks/src/main/bicep/modules/_rolesAssignment/_roleAssignmentinRgScope.bicep @@ -0,0 +1,43 @@ +/* + Copyright (c) 2021, Oracle and/or its affiliates. +Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +*/ + +/* +Description: assign roles cross resource group. +Usage: + module roleAssignment '_roleAssignmentinRgScope.bicep' = { + name: 'assign-role' + scope: resourceGroup( 0 +var ref_networkDeployment = _enableAppGWIngress ? networkingDeploymentYesAppGW : networkingDeploymentNoAppGW module pidNetworkingStart './_pids/_pid.bicep' = { name: 'pid-networking-start-deployment' @@ -77,113 +72,105 @@ module pidNetworkingStart './_pids/_pid.bicep' = { } } -module pidAppgwStart './_pids/_pid.bicep' = if (enableAppGWIngress) { - name: 'pid-app-gateway-start-deployment' +module pidLbStart './_pids/_pid.bicep' = if (const_enableLbService) { + name: 'pid-loadbalancer-service-start-deployment' params: { - name: _pidAppgwStart + name: _pidLbStart } } -// get key vault object in a resource group -resource existingKeyvault 'Microsoft.KeyVault/vaults@2019-09-01' existing = if (enableAppGWIngress) { - name: keyVaultName - scope: resourceGroup(keyVaultResourceGroup) +module pidDnsStart './_pids/_pid.bicep' = if (enableDNSConfiguration) { + name: 'pid-dns-start-deployment' + params: { + name: _pidDnsStart + } } -module appgwDeployment '_azure-resoruces/_appgateway.bicep' = if (enableAppGWIngress) { - name: 'app-gateway-deployment' +module dnsZoneDeployment '_azure-resoruces/_dnsZones.bicep' = if (enableDNSConfiguration && createDNSZone) { + name: 'dnszone-deployment' params: { - dnsNameforApplicationGateway: dnsNameforApplicationGateway - gatewayPublicIPAddressName: appGatewayPublicIPAddressName + dnszoneName: dnszoneName + tagsByResource: tagsByResource } dependsOn: [ - pidAppgwStart + pidNetworkingStart + pidDnsStart ] } -/* - Upload trusted root certificate to Azure Application Gateway - To set up e2e TLS/SSL communication between Azure Application Gateway and WebLogic admin server or WebLogic cluster. - The certificate must be the CA certificate of WebLogic Server identity. -*/ -module appgwBackendCertDeployment '_deployment-scripts/_ds-appgw-upload-trusted-root-certificate.bicep' = if (enableAppGWIngress && enableCustomSSL) { - name: 'app-gateway-backend-cert-deployment' +module installAgic '_deployment-scripts/_ds_install_agic.bicep' = if (enableAppGWIngress) { + name: 'install-agic' params: { - appgwName: enableAppGWIngress ? appgwDeployment.outputs.appGatewayName : 'null' - sslBackendRootCertData: existingKeyvault.getSecret(keyvaultBackendCertDataSecretName) + _globalResourceNameSuffix: _globalResourceNameSuffix + location: location identity: identity + aksClusterRGName: aksClusterRGName + appgwName: appGatewayName + aksClusterName: aksClusterName + azCliVersion: azCliVersion + tagsByResource: tagsByResource } dependsOn: [ - appgwDeployment + pidNetworkingStart ] } +module agicRoleAssignment '_rolesAssignment/_agicRoleAssignment.bicep' = if (enableAppGWIngress) { + name: 'allow-agic-access-current-resource-group' + params: { + aksClusterName: aksClusterName + aksClusterRGName: aksClusterRGName + } + dependsOn: [ + installAgic + ] +} - -module dnsZoneDeployment '_azure-resoruces/_dnsZones.bicep' = if (enableDNSConfiguration && createDNSZone) { - name: 'dnszone-deployment' +module agicNetworkContributorRoleAssignment '_rolesAssignment/_agicNetworkContributor.bicep' = if (enableAppGWIngress && newOrExistingVnetForApplicationGateway != 'new' && vnetRGNameForApplicationGateway != resourceGroup().name) { + name: 'allow-agic-access-vnet' + scope: resourceGroup(vnetRGNameForApplicationGateway) params: { - dnszoneName: dnszoneName + aksClusterName: aksClusterName + aksClusterRGName: aksClusterRGName } dependsOn: [ - pidNetworkingStart + installAgic ] } -module networkingDeployment '_deployment-scripts/_ds-create-networking.bicep' = if (enableAppGWIngress && appGatewayCertificateOption != const_appgwSSLCertOptionGenerateCert) { - name: 'ds-networking-deployment' +module validateAgic '_deployment-scripts/_ds_validate_agic.bicep' = if (enableAppGWIngress) { + name: 'validate-agic' params: { - _artifactsLocation: _artifactsLocation - _artifactsLocationSasToken: _artifactsLocationSasToken - appgwName: enableAppGWIngress ? appgwDeployment.outputs.appGatewayName : 'null' - appgwAlias: enableAppGWIngress ? appgwDeployment.outputs.appGatewayAlias : 'null' - appgwCertificateOption: appGatewayCertificateOption - appgwForAdminServer: appgwForAdminServer - appgwForRemoteConsole: appgwForRemoteConsole - appgwFrontendSSLCertData: existingKeyvault.getSecret(keyVaultSSLCertDataSecretName) - appgwFrontendSSLCertPsw: existingKeyvault.getSecret(keyVaultSSLCertPasswordSecretName) + _globalResourceNameSuffix: _globalResourceNameSuffix + location: location + identity: identity aksClusterRGName: aksClusterRGName aksClusterName: aksClusterName - dnszoneAdminConsoleLabel: dnszoneAdminConsoleLabel - dnszoneAdminT3ChannelLabel: dnszoneAdminT3ChannelLabel - dnszoneClusterLabel: dnszoneClusterLabel - dnszoneClusterT3ChannelLabel: dnszoneClusterT3ChannelLabel - dnszoneName: dnszoneName - dnszoneRGName: createDNSZone ? resourceGroup().name : dnszoneRGName - enableAppGWIngress: enableAppGWIngress - enableCookieBasedAffinity: enableCookieBasedAffinity - enableCustomSSL: enableCustomSSL - enableDNSConfiguration: enableDNSConfiguration - identity: identity - lbSvcValues: lbSvcValues - location: location - servicePrincipal: servicePrincipal - useInternalLB: useInternalLB - vnetName: enableAppGWIngress ? appgwDeployment.outputs.vnetName : 'null' - wlsDomainName: wlsDomainName - wlsDomainUID: wlsDomainUID + azCliVersion: azCliVersion + tagsByResource: tagsByResource } dependsOn: [ - appgwBackendCertDeployment - dnsZoneDeployment + agicRoleAssignment ] } -// Wrokaround for "Error BCP180: Function "getSecret" is not valid at this location. It can only be used when directly assigning to a module parameter with a secure decorator." -module networkingDeployment2 '_deployment-scripts/_ds-create-networking.bicep' = if (enableAppGWIngress && appGatewayCertificateOption == const_appgwSSLCertOptionGenerateCert) { - name: 'ds-networking-deployment-1' +module networkingDeploymentYesAppGW '_deployment-scripts/_ds-create-networking.bicep' = if (enableAppGWIngress) { + name: 'ds-networking-deployment-yes-appgw' params: { _artifactsLocation: _artifactsLocation _artifactsLocationSasToken: _artifactsLocationSasToken - appgwName: enableAppGWIngress ? appgwDeployment.outputs.appGatewayName : 'null' - appgwAlias: enableAppGWIngress ? appgwDeployment.outputs.appGatewayAlias : 'null' - appgwCertificateOption: appGatewayCertificateOption + _globalResourceNameSuffix: _globalResourceNameSuffix + appgwName: appGatewayName + appgwAlias: appGatewayAlias appgwForAdminServer: appgwForAdminServer appgwForRemoteConsole: appgwForRemoteConsole - appgwFrontendSSLCertData: existingKeyvault.getSecret(keyVaultSSLCertDataSecretName) - appgwFrontendSSLCertPsw: 'null' + appgwSslCert: appGatewaySslCert + appgwTrustedRootCert: appGatewayTrustedRootCert + appgwUsePrivateIP: appgwUsePrivateIP aksClusterRGName: aksClusterRGName aksClusterName: aksClusterName + azCliVersion: azCliVersion + createAKSCluster: createAKSCluster dnszoneAdminConsoleLabel: dnszoneAdminConsoleLabel dnszoneAdminT3ChannelLabel: dnszoneAdminT3ChannelLabel dnszoneClusterLabel: dnszoneClusterLabel @@ -191,38 +178,40 @@ module networkingDeployment2 '_deployment-scripts/_ds-create-networking.bicep' = dnszoneName: dnszoneName dnszoneRGName: createDNSZone ? resourceGroup().name : dnszoneRGName enableAppGWIngress: enableAppGWIngress - enableCustomSSL: enableCustomSSL enableCookieBasedAffinity: enableCookieBasedAffinity + enableCustomSSL: enableCustomSSL enableDNSConfiguration: enableDNSConfiguration identity: identity lbSvcValues: lbSvcValues location: location - servicePrincipal: servicePrincipal + tagsByResource: tagsByResource useInternalLB: useInternalLB - vnetName: enableAppGWIngress ? appgwDeployment.outputs.vnetName : 'null' wlsDomainName: wlsDomainName - wlsDomainUID: wlsDomainUID + wlsDomainUID: wlsDomainUID } dependsOn: [ - appgwBackendCertDeployment dnsZoneDeployment + validateAgic ] } -module networkingDeployment3 '_deployment-scripts/_ds-create-networking.bicep' = if (!enableAppGWIngress) { - name: 'ds-networking-deployment-2' +module networkingDeploymentNoAppGW '_deployment-scripts/_ds-create-networking.bicep' = if (!enableAppGWIngress) { + name: 'ds-networking-deployment-no-appgw' params: { _artifactsLocation: _artifactsLocation _artifactsLocationSasToken: _artifactsLocationSasToken + _globalResourceNameSuffix: _globalResourceNameSuffix appgwName: 'null' appgwAlias: 'null' - appgwCertificateOption: appGatewayCertificateOption appgwForAdminServer: appgwForAdminServer appgwForRemoteConsole: appgwForRemoteConsole - appgwFrontendSSLCertData: 'null' - appgwFrontendSSLCertPsw: 'null' + appgwSslCert: appGatewaySslCert + appgwTrustedRootCert: appGatewayTrustedRootCert + appgwUsePrivateIP: appgwUsePrivateIP aksClusterRGName: aksClusterRGName aksClusterName: aksClusterName + azCliVersion: azCliVersion + createAKSCluster: createAKSCluster dnszoneAdminConsoleLabel: dnszoneAdminConsoleLabel dnszoneAdminT3ChannelLabel: dnszoneAdminT3ChannelLabel dnszoneClusterLabel: dnszoneClusterLabel @@ -236,24 +225,36 @@ module networkingDeployment3 '_deployment-scripts/_ds-create-networking.bicep' = identity: identity lbSvcValues: lbSvcValues location: location - servicePrincipal: servicePrincipal + tagsByResource: tagsByResource useInternalLB: useInternalLB - vnetName: 'null' wlsDomainName: wlsDomainName wlsDomainUID: wlsDomainUID } dependsOn: [ dnsZoneDeployment + validateAgic + ] +} + +module pidLbEnd './_pids/_pid.bicep' = if (const_enableLbService) { + name: 'pid-loadbalancer-service-end-deployment' + params: { + name: _pidLbEnd + } + dependsOn: [ + networkingDeploymentYesAppGW + networkingDeploymentNoAppGW ] } -module pidAppgwEnd './_pids/_pid.bicep' = if (enableAppGWIngress) { - name: 'pid-app-gateway-end-deployment' +module pidDnsEnd './_pids/_pid.bicep' = if (enableDNSConfiguration) { + name: 'pid-dns-end-deployment' params: { - name: _pidAppgwEnd + name: _pidDnsEnd } dependsOn: [ - appgwDeployment + networkingDeploymentYesAppGW + networkingDeploymentNoAppGW ] } @@ -263,17 +264,16 @@ module pidNetworkingEnd './_pids/_pid.bicep' = { name: _pidNetworkingEnd } dependsOn: [ - networkingDeployment - networkingDeployment2 - networkingDeployment3 + pidLbEnd + pidDnsEnd ] } -output adminConsoleExternalUrl string = enableAppGWIngress ? (enableDNSConfiguration ? format('http://{0}console', const_appgwAdminCustomDNSAlias) : format('http://{0}/console', appgwDeployment.outputs.appGatewayAlias)) : ref_networkDeployment.outputs.adminConsoleLBUrl.value -output adminConsoleExternalSecuredUrl string = enableAppGWIngress && enableCustomSSL && enableDNSConfiguration ? format('https://{0}console', const_appgwAdminCustomDNSAlias) : ref_networkDeployment.outputs.adminConsoleLBSecuredUrl.value -output adminRemoteConsoleUrl string = enableAppGWIngress ? (enableDNSConfiguration ? format('http://{0}remoteconsole', const_appgwAdminCustomDNSAlias) : format('http://{0}/remoteconsole', appgwDeployment.outputs.appGatewayAlias)) : ref_networkDeployment.outputs.adminRemoteUrl.value -output adminRemoteConsoleSecuredUrl string = enableAppGWIngress && enableCustomSSL && enableDNSConfiguration ? format('https://{0}remoteconsole', const_appgwAdminCustomDNSAlias) : ref_networkDeployment.outputs.adminRemoteSecuredUrl.value -output adminServerT3ChannelUrl string = ref_networkDeployment.outputs.adminServerT3LBUrl.value -output clusterExternalUrl string = enableAppGWIngress ? (enableDNSConfiguration ? format('http://{0}', const_appgwCustomDNSAlias) : appgwDeployment.outputs.appGatewayURL) : ref_networkDeployment.outputs.clusterLBUrl.value -output clusterExternalSecuredUrl string = enableAppGWIngress ? (enableDNSConfiguration ? format('https://{0}', const_appgwCustomDNSAlias) : appgwDeployment.outputs.appGatewaySecuredURL) : ref_networkDeployment.outputs.clusterLBSecuredUrl.value -output clusterT3ChannelUrl string = ref_networkDeployment.outputs.clusterT3LBUrl.value +output adminConsoleExternalEndpoint string = enableAppGWIngress ? (enableDNSConfiguration ? format('http://{0}console', const_appgwAdminCustomDNSAlias) : format('http://{0}/console', appGatewayAlias)) : ref_networkDeployment.outputs.adminConsoleLBEndpoint +output adminConsoleExternalSecuredEndpoint string = enableAppGWIngress && enableCustomSSL && enableDNSConfiguration ? format('https://{0}console', const_appgwAdminCustomDNSAlias) : ref_networkDeployment.outputs.adminConsoleLBSecuredEndpoint +output adminRemoteConsoleEndpoint string = enableAppGWIngress ? (enableDNSConfiguration ? format('http://{0}remoteconsole', const_appgwAdminCustomDNSAlias) : format('http://{0}/remoteconsole', appGatewayAlias)) : ref_networkDeployment.outputs.adminRemoteEndpoint +output adminRemoteConsoleSecuredEndpoint string = enableAppGWIngress && enableCustomSSL && enableDNSConfiguration ? format('https://{0}remoteconsole', const_appgwAdminCustomDNSAlias) : ref_networkDeployment.outputs.adminRemoteSecuredEndpoint +output adminServerT3ChannelEndpoint string = format('{0}://{1}', enableCustomSSL ? 't3s' : 't3', ref_networkDeployment.outputs.adminServerT3LBEndpoint) +output clusterExternalEndpoint string = enableAppGWIngress ? (enableDNSConfiguration ? format('http://{0}', const_appgwCustomDNSAlias) : appGatewayURL) : ref_networkDeployment.outputs.clusterLBEndpoint +output clusterExternalSecuredEndpoint string = enableAppGWIngress ? (enableDNSConfiguration ? format('https://{0}', const_appgwCustomDNSAlias) : appGatewaySecuredURL) : ref_networkDeployment.outputs.clusterLBSecuredEndpoint +output clusterT3ChannelEndpoint string = format('{0}://{1}', enableCustomSSL ? 't3s' : 't3', ref_networkDeployment.outputs.clusterT3LBEndpoint) diff --git a/weblogic-azure-aks/src/main/bicep/modules/setupDBConnection.bicep b/weblogic-azure-aks/src/main/bicep/modules/setupDBConnection.bicep index e5a4bf977..d2857cc74 100644 --- a/weblogic-azure-aks/src/main/bicep/modules/setupDBConnection.bicep +++ b/weblogic-azure-aks/src/main/bicep/modules/setupDBConnection.bicep @@ -17,6 +17,7 @@ Parameters - createOrUpdate: create a new data source connection, or update an existing data source connection. - delete: delete an existing data source connection - dbPassword: Password for Database + - dbGlobalTranPro: Determines the transaction protocol (global transaction processing behavior) for the data source.. - dbUser: User id of Database - dsConnectionURL: JDBC Connection String - identity: Azure user managed identity used, make sure the identity has permission to create/update/delete Azure resources. It's recommended to assign "Contributor" role. @@ -29,7 +30,7 @@ Build and run - Run command `az deployment group create -f setupDBConnection.json -p parameters.json -g ` */ -param _artifactsLocation string = '' +param _artifactsLocation string = 'https://raw.githubusercontent.com/oracle/weblogic-azure/main/weblogic-azure-aks/src/main/arm/' @secure() param _artifactsLocationSasToken string = '' @@ -39,6 +40,8 @@ param aksClusterName string = '' 'oracle' 'postgresql' 'sqlserver' + 'mysql' + 'otherdb' ]) @description('One of the supported database types') param databaseType string = 'oracle' @@ -48,6 +51,9 @@ param databaseType string = 'oracle' ]) @description('createOrUpdate: create a new data source connection, or update an existing data source connection. delete: delete an existing data source connection') param dbConfigurationType string = 'createOrUpdate' +@description('Determines the transaction protocol (global transaction processing behavior) for the data source.') +param dbGlobalTranPro string = 'EmulateTwoPhaseCommit' +@secure() @description('Password for Database') param dbPassword string = newGuid() @description('User id of Database') @@ -55,10 +61,13 @@ param dbUser string = 'contosoDbUser' @description('JDBC Connection String') param dsConnectionURL string = 'jdbc:postgresql://contoso.postgres.database.azure.com:5432/postgres' -param identity object +param identity object = {} @description('JNDI Name for JDBC Datasource') param jdbcDataSourceName string = 'jdbc/contoso' +@description('tags for the resources') +param tagsByResource object = {} +param utcValue string = utcNow() @description('UID of WebLogic domain, used in WebLogic Operator.') param wlsDomainUID string = 'sample-domain1' @secure() @@ -66,26 +75,53 @@ param wlsPassword string @description('User name for WebLogic Administrator.') param wlsUserName string = 'weblogic' +// This template is used for post deployment, hard code the CLI version with a variable. +var const_azCliVersion = '2.33.1' +var _objTagsByResource = { + 'Microsoft.Monitor/accounts': contains(tagsByResource, 'Microsoft.Monitor/accounts') ? tagsByResource['Microsoft.Monitor/accounts'] : json('{}') + 'Microsoft.ContainerService/managedClusters': contains(tagsByResource, 'Microsoft.ContainerService/managedClusters') ? tagsByResource['Microsoft.ContainerService/managedClusters'] : json('{}') + 'Microsoft.Network/applicationGateways': contains(tagsByResource, 'Microsoft.Network/applicationGateways') ? tagsByResource['Microsoft.Network/applicationGateways'] : json('{}') + 'Microsoft.ContainerRegistry/registries': contains(tagsByResource, 'Microsoft.ContainerRegistry/registries') ? tagsByResource['Microsoft.ContainerRegistry/registries'] : json('{}') + 'Microsoft.Compute/virtualMachines': contains(tagsByResource, 'Microsoft.Compute/virtualMachines') ? tagsByResource['Microsoft.Compute/virtualMachines'] : json('{}') + 'Virtual machine extension': contains(tagsByResource, 'Virtual machine extension') ? tagsByResource['Virtual machine extension'] : json('{}') + 'Microsoft.Network/virtualNetworks': contains(tagsByResource, 'Microsoft.Network/virtualNetworks') ? tagsByResource['Microsoft.Network/virtualNetworks'] : json('{}') + 'Microsoft.Network/networkInterfaces': contains(tagsByResource, 'Microsoft.Network/networkInterfaces') ? tagsByResource['Microsoft.Network/networkInterfaces'] : json('{}') + 'Microsoft.Network/networkSecurityGroups': contains(tagsByResource, 'Microsoft.Network/networkSecurityGroups') ? tagsByResource['Microsoft.Network/networkSecurityGroups'] : json('{}') + 'Microsoft.Network/publicIPAddresses': contains(tagsByResource, 'Microsoft.Network/publicIPAddresses') ? tagsByResource['Microsoft.Network/publicIPAddresses'] : json('{}') + 'Microsoft.Storage/storageAccounts': contains(tagsByResource, 'Microsoft.Storage/storageAccounts') ? tagsByResource['Microsoft.Storage/storageAccounts'] : json('{}') + 'Microsoft.KeyVault/vaults': contains(tagsByResource, 'Microsoft.KeyVault/vaults') ? tagsByResource['Microsoft.KeyVault/vaults'] : json('{}') + 'Microsoft.ManagedIdentity/userAssignedIdentities': contains(tagsByResource, 'Microsoft.ManagedIdentity/userAssignedIdentities') ? tagsByResource['Microsoft.ManagedIdentity/userAssignedIdentities'] : json('{}') + 'Microsoft.Network/dnszones': contains(tagsByResource, 'Microsoft.Network/dnszones') ? tagsByResource['Microsoft.Network/dnszones'] : json('{}') + 'Microsoft.OperationalInsights/workspaces': contains(tagsByResource, 'Microsoft.OperationalInsights/workspaces') ? tagsByResource['Microsoft.OperationalInsights/workspaces'] : json('{}') + 'Microsoft.Resources/deploymentScripts': contains(tagsByResource, 'Microsoft.Resources/deploymentScripts') ? tagsByResource['Microsoft.Resources/deploymentScripts'] : json('{}') +} + module pids './_pids/_pid.bicep' = { name: 'initialization' } module configDataSource './_setupDBConnection.bicep' = { - name: 'create-update--delete-datasource' + name: 'create-update-delete-datasource' params:{ _pidEnd: pids.outputs.dbEnd + _pidOtherDb: pids.outputs.otherDb _pidStart: pids.outputs.dbStart _artifactsLocation: _artifactsLocation _artifactsLocationSasToken: _artifactsLocationSasToken + _globalResourceNameSuffix: uniqueString(utcValue) aksClusterName: aksClusterName aksClusterRGName: resourceGroup().name + azCliVersion: const_azCliVersion databaseType: databaseType dbConfigurationType: dbConfigurationType + dbGlobalTranPro: dbGlobalTranPro dbPassword: dbPassword dbUser: dbUser dsConnectionURL: dsConnectionURL identity: identity jdbcDataSourceName: jdbcDataSourceName + location: resourceGroup().location + tagsByResource: _objTagsByResource wlsDomainUID: wlsDomainUID wlsPassword: wlsPassword wlsUserName: wlsUserName diff --git a/weblogic-azure-aks/src/main/bicep/modules/setupWebLogicCluster.bicep b/weblogic-azure-aks/src/main/bicep/modules/setupWebLogicCluster.bicep index 8281508fc..47666bdee 100644 --- a/weblogic-azure-aks/src/main/bicep/modules/setupWebLogicCluster.bicep +++ b/weblogic-azure-aks/src/main/bicep/modules/setupWebLogicCluster.bicep @@ -1,4 +1,4 @@ -// Copyright (c) 2021, Oracle Corporation and/or its affiliates. +// Copyright (c) 2021, 2024, Oracle Corporation and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. /* @@ -17,8 +17,11 @@ param _artifactsLocation string = deployment().properties.templateLink.uri @secure() param _artifactsLocationSasToken string = '' -param _pidEnd string -param _pidStart string +param _pidEnd string = 'pid-wls-end' +param _pidStart string = 'pid-wls-start' +param _pidSSLEnd string = 'pid-ssl-end' +param _pidSSLStart string = 'pid-ssl-start' +param _globalResourceNameSuffix string @description('true to use resource or workspace permissions. false to require workspace permissions.') param aciResourcePermissions bool = true @description('Number of days to retain data in Azure Monitor workspace.') @@ -26,18 +29,22 @@ param aciRetentionInDays int = 120 @description('Pricing tier: PerGB2018 or legacy tiers (Free, Standalone, PerNode, Standard or Premium) which are not available to all customers.') param aciWorkspaceSku string = 'pergb2018' param acrName string = '' +param acrResourceGroupName string = '' +param aksAgentAvailabilityZones array = [] @maxLength(12) @minLength(1) @description('The name for this node pool. Node pool must contain only lowercase letters and numbers. For Linux node pools the name cannot be longer than 12 characters.') -param aksAgentPoolName string = 'agentpool' +param aksAgentPoolName string = 'nodepool1' @maxValue(10000) @minValue(1) -@description('The number of nodes that should be created along with the cluster. You will be able to resize the cluster later.') +@description('Set the minimum node count for the cluster..') param aksAgentPoolNodeCount int = 3 +@maxValue(1000) +@minValue(3) +@description('Set the maximum node count for the cluster.') +param aksAgentPoolNodeMaxCount int = 5 @description('The size of the virtual machines that will form the nodes in the cluster. This cannot be changed after creating the cluster') -param aksAgentPoolVMSize string = 'Standard_DS2_v2' -@description('Prefix for cluster name. Only The name can contain only letters, numbers, underscores and hyphens. The name must start with letter or number.') -param aksClusterNamePrefix string = 'wlsonaks' +param vmSize string = 'Standard_DS2_v2' @description('Resource group name of an existing AKS cluster.') param aksClusterRGName string = '' @description('Name of an existing AKS cluster.') @@ -48,31 +55,41 @@ param aksVersion string = 'default' param appPackageUrls array = [] @description('The number of managed server to start.') param appReplicas int = 2 -@description('true to create a new Azure Container Registry.') -param createACR bool = false +param azCliVersion string = '' +param cpuPlatform string = 'linux/amd64' @description('true to create a new AKS cluster.') param createAKSCluster bool = true -param createStorageAccount bool = false +param databaseType string = 'oracle' +param dbDriverLibrariesUrls array = [] @description('In addition to the CPU and memory metrics included in AKS by default, you can enable Container Insights for more comprehensive data on the overall performance and health of your cluster. Billing is based on data ingestion and retention settings.') param enableAzureMonitoring bool = false @description('true to create persistent volume using file share.') param enableCustomSSL bool = false param enableAdminT3Tunneling bool = false param enableClusterT3Tunneling bool = false +param enablePswlessConnection bool = false param enablePV bool = false +param fileShareName string = '' @description('An user assigned managed identity. Make sure the identity has permission to create/update/delete/list Azure resources.') -param identity object -param location string = 'eastus' +param identity object = {} +param isSSOSupportEntitled bool +param location string @description('Name prefix of managed server.') param managedServerPrefix string = 'managed-server' @secure() -@description('Password of Oracle SSO account.') +@description('Auth token of Oracle SSO account.') param ocrSSOPSW string @description('User name of Oracle SSO account.') param ocrSSOUser string -param storageAccountName string +param storageAccountName string = 'stg-contoso' param t3ChannelAdminPort int = 7005 param t3ChannelClusterPort int = 8011 +@description('${label.tagsLabel}') +param tagsByResource object +param userProvidedAcr string = 'null' +param userProvidedAcrRgName string = 'null' +param userProvidedImagePath string = 'null' +param useOracleImage bool = true @secure() @description('Password for model WebLogic Deploy Tooling runtime encrytion.') param wdtRuntimePassword string @@ -125,6 +142,18 @@ module pidStart './_pids/_pid.bicep' = { } } +module pidSSLStart './_pids/_pid.bicep' = if (enableCustomSSL) { + name: 'wls-ssl-start-pid-deployment' + params: { + name: _pidSSLStart + } +} + +resource existingAKSCluster 'Microsoft.ContainerService/managedClusters@${azure.apiVersionForManagedClusters}' existing = if (!createAKSCluster) { + name: aksClusterName + scope: resourceGroup(aksClusterRGName) +} + /* * Deploy AKS cluster */ @@ -134,26 +163,16 @@ module aksClusterDeployment './_azure-resoruces/_aks.bicep' = if (createAKSClust aciResourcePermissions: aciResourcePermissions aciRetentionInDays: aciRetentionInDays aciWorkspaceSku: aciWorkspaceSku + agentAvailabilityZones: aksAgentAvailabilityZones aksAgentPoolName: aksAgentPoolName aksAgentPoolNodeCount: aksAgentPoolNodeCount - aksAgentPoolVMSize: aksAgentPoolVMSize - aksClusterNamePrefix: aksClusterNamePrefix + aksAgentPoolNodeMaxCount: aksAgentPoolNodeMaxCount + aksAgentPoolVMSize: vmSize + aksClusterName: aksClusterName aksVersion: aksVersion enableAzureMonitoring: enableAzureMonitoring location: location - } - dependsOn: [ - pidStart - ] -} - -/* -* Deploy ACR -*/ -module acrDeployment './_azure-resoruces/_acr.bicep' = if (createACR) { - name: 'acr-deployment' - params: { - location: location + tagsByResource: tagsByResource } dependsOn: [ pidStart @@ -161,11 +180,13 @@ module acrDeployment './_azure-resoruces/_acr.bicep' = if (createACR) { } // enableAppGWIngress: if true, will create storage for certificates. -module storageDeployment './_azure-resoruces/_storage.bicep' = if (createStorageAccount) { +module storageDeployment './_azure-resoruces/_storage.bicep' = { name: 'storage-deployment' params: { + fileShareName: fileShareName location: location storageAccountName: storageAccountName + tagsByResource: tagsByResource } dependsOn: [ pidStart @@ -180,16 +201,26 @@ module wlsDomainDeployment './_deployment-scripts/_ds-create-wls-cluster.bicep' params: { _artifactsLocation: _artifactsLocation _artifactsLocationSasToken: _artifactsLocationSasToken + _globalResourceNameSuffix: _globalResourceNameSuffix + aksAgentPoolName: aksAgentPoolName aksClusterRGName: createAKSCluster ? resourceGroup().name : aksClusterRGName - aksClusterName: createAKSCluster ? aksClusterDeployment.outputs.aksClusterName : aksClusterName - acrName: createACR ? acrDeployment.outputs.acrName : acrName + aksClusterName: aksClusterName + acrName: useOracleImage ? acrName : userProvidedAcr + acrResourceGroupName: useOracleImage ? acrResourceGroupName : userProvidedAcrRgName appPackageUrls: appPackageUrls appReplicas: appReplicas + azCliVersion: azCliVersion + cpuPlatform: cpuPlatform + databaseType: databaseType + dbDriverLibrariesUrls: dbDriverLibrariesUrls enableCustomSSL: enableCustomSSL enableAdminT3Tunneling: enableAdminT3Tunneling enableClusterT3Tunneling: enableClusterT3Tunneling + enablePswlessConnection: enablePswlessConnection enablePV: enablePV + fileShareName: fileShareName identity: identity + isSSOSupportEntitled: isSSOSupportEntitled location: location managedServerPrefix: managedServerPrefix ocrSSOUser: ocrSSOUser @@ -197,6 +228,9 @@ module wlsDomainDeployment './_deployment-scripts/_ds-create-wls-cluster.bicep' storageAccountName: storageAccountName t3ChannelAdminPort: t3ChannelAdminPort t3ChannelClusterPort: t3ChannelClusterPort + tagsByResource: tagsByResource + userProvidedImagePath: userProvidedImagePath + useOracleImage: useOracleImage wdtRuntimePassword: wdtRuntimePassword wlsClusterSize: wlsClusterSize wlsCPU: wlsCPU @@ -218,11 +252,20 @@ module wlsDomainDeployment './_deployment-scripts/_ds-create-wls-cluster.bicep' } dependsOn: [ aksClusterDeployment - acrDeployment storageDeployment ] } +module pidSSLEnd './_pids/_pid.bicep' = if (enableCustomSSL) { + name: 'wls-ssl-end-pid-deployment' + params: { + name: _pidSSLEnd + } + dependsOn: [ + wlsDomainDeployment + ] +} + /* * Deploy a pid to tract an offer deployment ends * Make sure all the dependencies added to dependsOn array @@ -237,9 +280,10 @@ module pidEnd './_pids/_pid.bicep' = { ] } -output aksClusterName string = createAKSCluster ? aksClusterDeployment.outputs.aksClusterName : aksClusterName +output aksClusterName string = aksClusterName output aksClusterRGName string = createAKSCluster ? resourceGroup().name : aksClusterRGName -output adminServerUrl string = format('http://{0}-admin-server.{0}-ns.svc.cluster.local:7001/console', wlsDomainUID) -output adminServerT3InternalUrl string = enableAdminT3Tunneling ? format('{0}://{1}-admin-server.{1}-ns.svc.cluster.local:{2}', enableCustomSSL ? 't3s' : 't3', wlsDomainUID, t3ChannelAdminPort): '' -output clusterSVCUrl string = format('http://{0}-cluster-cluster-1.{0}-ns.svc.cluster.local:8001/', wlsDomainUID) -output clusterT3InternalUrl string = enableClusterT3Tunneling ? format('{0}://{1}-cluster-cluster-1.{1}-ns.svc.cluster.local:{2}', enableCustomSSL ? 't3s' : 't3', wlsDomainUID, t3ChannelClusterPort): '' +output aksNodeRgName string = createAKSCluster? aksClusterDeployment.outputs.aksNodeRgName : existingAKSCluster.properties.nodeResourceGroup +output adminServerEndPoint string = format('http://{0}-admin-server.{0}-ns.svc.cluster.local:7001/console', wlsDomainUID) +output adminServerT3InternalEndPoint string = enableAdminT3Tunneling ? format('{0}://{1}-admin-server.{1}-ns.svc.cluster.local:{2}', enableCustomSSL ? 't3s' : 't3', wlsDomainUID, t3ChannelAdminPort): '' +output clusterEndPoint string = format('http://{0}-cluster-cluster-1.{0}-ns.svc.cluster.local:8001/', wlsDomainUID) +output clusterT3InternalEndPoint string = enableClusterT3Tunneling ? format('{0}://{1}-cluster-cluster-1.{1}-ns.svc.cluster.local:{2}', enableCustomSSL ? 't3s' : 't3', wlsDomainUID, t3ChannelClusterPort): '' diff --git a/weblogic-azure-aks/src/main/bicep/modules/updateWebLogicApplications.bicep b/weblogic-azure-aks/src/main/bicep/modules/updateWebLogicApplications.bicep index 8468ff787..c94c548ef 100644 --- a/weblogic-azure-aks/src/main/bicep/modules/updateWebLogicApplications.bicep +++ b/weblogic-azure-aks/src/main/bicep/modules/updateWebLogicApplications.bicep @@ -20,7 +20,8 @@ Parameters - storageAccountName: Storage account name. - containerName: container name. - identity: Azure user managed identity used, make sure the identity has permission to create/update/delete Azure resources. It's recommended to assign "Contributor" role. - - ocrSSOPSW: Password of Oracle SSO account. The script will pull image from Oracle Container Registry (OCR), Oracle account is required. Make sure the account has checkout WebLogic images. + - isSSOSupportEntitled: Is the specified SSO account associated with an active Oracle support contract? + - ocrSSOPSW: Auth token of Oracle SSO account. The script will pull image from Oracle Container Registry (OCR), Oracle account is required. Make sure the account has checkout WebLogic images. - ocrSSOUser: User name of Oracle SSO account. - wlsDomainName: Name of the domain that you are going to update. Make sure it's the same with the initial cluster deployment. - wlsDomainUID: UID of the domain that you are going to update. Make sure it's the same with the initial cluster deployment. @@ -32,7 +33,7 @@ Build and run - Run command `az deployment group create -f updateWebLogicApplications.json -p parameters.json -g ` */ -param _artifactsLocation string = '' +param _artifactsLocation string = 'https://raw.githubusercontent.com/oracle/weblogic-azure/main/weblogic-azure-aks/src/main/arm/' @secure() param _artifactsLocationSasToken string = '' @@ -50,13 +51,15 @@ param appPackageFromStorageBlob object = { @description('Url array of Java EE application locations.') param appPackageUrls array = [] -param identity object +param identity object = {} +@description('Is the specified SSO account associated with an active Oracle support contract?') +param isSSOSupportEntitled bool = false @secure() -@description('Password of Oracle SSO account.') -param ocrSSOPSW string +@description('Auth token of Oracle SSO account.') +param ocrSSOPSW string = 'null' @description('User name of Oracle SSO account.') -param ocrSSOUser string +param ocrSSOUser string = 'null' @description('Name of WebLogic domain to create.') param wlsDomainName string = 'domain1' @@ -64,6 +67,14 @@ param wlsDomainName string = 'domain1' param wlsDomainUID string = 'sample-domain1' @description('Docker tag that comes after "container-registry.oracle.com/middleware/weblogic:"') param wlsImageTag string = '12.2.1.4' +@description('User provided ACR for base image') +param userProvidedAcr string = 'null' +@description('User provided base image path') +param userProvidedImagePath string = 'null' +@description('Use Oracle images or user provided patched images') +param useOracleImage bool = true + +var const_azCLIVersion = '2.33.1' module pids './_pids/_pid.bicep' = { name: 'initialization' @@ -86,15 +97,20 @@ module updateWLSApplications '_deployment-scripts/_ds_update-applications.bicep' _artifactsLocationSasToken: _artifactsLocationSasToken aksClusterRGName: aksClusterRGName aksClusterName: aksClusterName - acrName: acrName + acrName: useOracleImage ? acrName : userProvidedAcr appPackageUrls: appPackageUrls appPackageFromStorageBlob: appPackageFromStorageBlob + azCliVersion: const_azCLIVersion identity: identity + isSSOSupportEntitled: isSSOSupportEntitled + location: resourceGroup().location ocrSSOPSW: ocrSSOPSW ocrSSOUser: ocrSSOUser wlsDomainName: wlsDomainName wlsDomainUID: wlsDomainUID wlsImageTag: wlsImageTag + userProvidedImagePath: userProvidedImagePath + useOracleImage: useOracleImage } dependsOn:[ pidStart diff --git a/weblogic-azure-aks/src/main/resources/aks_tooling_well_tested_versions.json b/weblogic-azure-aks/src/main/resources/aks_tooling_well_tested_versions.json new file mode 100644 index 000000000..bb6f1efe6 --- /dev/null +++ b/weblogic-azure-aks/src/main/resources/aks_tooling_well_tested_versions.json @@ -0,0 +1,12 @@ +{ + "name": "AKS toolings used in WebLogic on AKS offer", + "description": "The versions are known to work for all the features of Azure WebLogic on AKS offer.", + "items": [ + { + "key": "keda", + "description": "KEDA for autoscaling", + "version": "2.14.2", + "testedDate": "2024-05-07" + } + ] +} diff --git a/weblogic-azure-aks/src/main/resources/aks_well_tested_version.json b/weblogic-azure-aks/src/main/resources/aks_well_tested_version.json new file mode 100644 index 000000000..241909628 --- /dev/null +++ b/weblogic-azure-aks/src/main/resources/aks_well_tested_version.json @@ -0,0 +1,6 @@ +{ + "name": "Known-good version of Azure Kubernetes Service", + "description": "This version is known to work for all the features of Azure WebLogic on AKS offer.", + "value": "1.31.7", + "testedDate": "2025-05-08" +} diff --git a/weblogic-azure-aks/src/main/resources/azure-identity-extensions.xml b/weblogic-azure-aks/src/main/resources/azure-identity-extensions.xml new file mode 100644 index 000000000..10dd0e771 --- /dev/null +++ b/weblogic-azure-aks/src/main/resources/azure-identity-extensions.xml @@ -0,0 +1,21 @@ + + + + 4.0.0 + com.oracle.weblogic.azure + passwordless-db + 1.0-SNAPSHOT + jar + + 11 + 11 + + + + com.azure + azure-identity-extensions + 1.2.2 + + + diff --git a/weblogic-azure-aks/src/main/resources/diagrams/wls-aks-diagram-autoscaling.vsdx b/weblogic-azure-aks/src/main/resources/diagrams/wls-aks-diagram-autoscaling.vsdx new file mode 100644 index 000000000..39ab6c68e Binary files /dev/null and b/weblogic-azure-aks/src/main/resources/diagrams/wls-aks-diagram-autoscaling.vsdx differ diff --git a/weblogic-azure-aks/src/main/resources/marketing-artifacts/README.md b/weblogic-azure-aks/src/main/resources/marketing-artifacts/README.md new file mode 100644 index 000000000..10d2ba5fe --- /dev/null +++ b/weblogic-azure-aks/src/main/resources/marketing-artifacts/README.md @@ -0,0 +1,53 @@ +

    Offer listing

    + +

    Name

    + +Oracle WebLogic Server on the Azure Kubernetes Service + +

    Oracle WebLogic Server is a scalable, enterprise-ready Java application server.

    + +

    Description

    + +

    The Oracle WebLogic Server (WLS) on Azure Kubernetes Service (AKS) offer lets you embrace cloud computing by providing greater choice and flexibility for WLS migration. The offer enables you to move WLS workloads to AKS as quickly and easily as possible by automating the provisioning of a number of Java and Azure resources. The automatically provisioned resources include an AKS cluster, the WebLogic Kubernetes Operator, WLS Docker images and the Azure Container Registry (ACR). It is possible to use an existing AKS cluster or ACR instance with the offer if desired. The offer also supports configuring load balancing with Azure App Gateway or the Azure Load Balancer, DNS configuration, SSL/TLS configuration, easing database connectivity, publishing metrics to Azure Monitor as well as mounting Azure Files as Kubernetes Persistent Volumes. After the offer performs most boilerplate resource provisioning and configuration, you can focus on deploying your WLS application to AKS, typically through a DevOps tool such as GitHub Actions and tools from the WebLogic Kubernetes ToolKit such as the WebLogic Image Tool and WebLogic Deploy Tooling. You are also completely free to customize the deployment further.

    + +

    This offer is Bring-Your-Own-License. It assumes you have already procured the appropriate licenses with Oracle and are properly licensed to run offers in Microsoft Azure.

    + +

    If you want to provide feedback on this offer, stay updated on the roadmap, or work closely on your migration scenarios with the engineering team developing this offer, select the CONTACT ME button on the marketplace WebLogic on Azure offer overview page linked below. The opportunity to collaborate on a migration scenario is free while the offers are under active development.

    + +

    Search keywords

    + +Java +Java EE +WebLogic + +

    Privacy policy link

    + +https://www.oracle.com/legal/privacy/privacy-policy.html + +

    Useful links

    + +[Overview](https://www.oracle.com/middleware/weblogic/) + +[WebLogic on Azure](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/oracle.oraclelinux-wls-cluster) + +[Learn More](https://www.oracle.com/middleware/technologies/weblogic.html) + +

    Videos

    + +

    Name

    + +WebLogic on AKS + +

    Link

    + +https://www.youtube.com/watch?v=gFS-64XQorA + +

    Thumbnail

    + + + +LICENSE + +Copyright (c) 2021 Oracle and/or its affiliates. + +Released under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl/. diff --git a/weblogic-azure-aks/src/main/resources/marketing-artifacts/partner-center.html b/weblogic-azure-aks/src/main/resources/marketing-artifacts/partner-center.html new file mode 100644 index 000000000..1b9ff9af2 --- /dev/null +++ b/weblogic-azure-aks/src/main/resources/marketing-artifacts/partner-center.html @@ -0,0 +1,68 @@ +

    CONTACT ME offer

    +

    Name

    +

    Oracle WebLogic Server on Azure

    +

    Search results summary

    +

    Oracle WebLogic Server is a scalable, enterprise-ready Java application server.

    +

    Description (5000 characters, including basic HTML markup)

    +

    Oracle WebLogic Server (WLS) is an industry-leading Java runtime powering some of the most mission-critical enterprise applications + across the globe. Oracle and Microsoft collaborate to fully enable WLS on both Azure Virtual Machines and the Azure Kubernetes + Service (AKS). Joint solutions make it easier to migrate your application to the cloud by automating most boilerplate Azure and + Java resource provisioning and configuration tasks. Once initial provisioning is complete, you are completely free to customize + deployments further.

    +

    The currently available offers are linked in the learn more section at the bottom of this page.

    +

    You can reach out to the engineering team developing these offers by clicking the CONTACT ME button. Program managers, + architects and engineers will get in touch and can assist you for free with your Azure migration.

    +

    Links

    + + +

    Azure Application Offer

    +

    Name

    +

    Oracle WebLogic Server on Azure Kubernetes Service

    +

    Search results summary

    +

    Provisions an Oracle WebLogic Server dynamic cluster on Azure Kubernetes Service

    +

    Short description

    +

    Provisions an Oracle WebLogic Server dynamic cluster on the Azure Kubernetes Service. Integration options include Azure App Gateway, +Azure Container Registry, Azure Files, Azure Application Insights and various databases.

    +

    Description

    +

    Oracle WebLogic Server (WLS) is an industry-leading Java runtime powering some of the most mission-critical enterprise applications + across the globe. This solution automates most boilerplate steps to provision WLS on an Azure Kubernetes Service (AKS) + cluster. Once initial provisioning is complete, you are completely free to customize deployments further. The solution is jointly + developed by Oracle and Microsoft.

    +

    The solution supports WLS Enterprise Edition 12.2.1.4, and 14.1.1.0.

    +

    The following resources are automatically provisioned by the offer.

    +
      +
    • AKS cluster (alternatively, you can deploy to an existing AKS cluster)
    • +
    • Azure Container Registry (ACR) instance (alternatively, you can use an existing ACR instance)
    • +
    • WebLogic dynamic cluster with specified number of Managed Servers
    • +
    • Admin Server
    • +
    • WebLogic Domain
    • +
    • WebLogic Kubernetes Operator
    • +
    • Choice of Azure Application Gateway or AKS standard load balancer
    • +
    • Custom application deployment using domain home in image - optional
    • +
    • Configured data source connection (Oracle DB, Azure SQL, Azure MySQL, Azure PostgreSQL) - optional
    • +
    • Azure Container Insights and workspace monitoring WLS on AKS - optional
    • +
    • Azure File share named weblogic mounted to /shared as Persistent Volume - optional
    • +
    • Virtual network and subnet
    • +
    • Azure Storage Account
    • +
    +

    This offer is Bring-Your-Own-License. It assumes you have already procured the appropriate licenses with Oracle and are properly +licensed to run offers in Microsoft Azure.

    +

    Oracle and Microsoft also provide basic step-by-step instructions on getting started with WLS and AKS without automated +provisioning.

    +

    Oracle and Microsoft provide similar solutions targeting WLS on Azure VMs (single instance or cluster). These options are linked in +the Learn more section below.

    +

    You can reach out to the engineering team developing these offers by clicking the CONTACT ME button on +the marketplace WebLogic on Azure overview page. Program managers, architects and engineers will get in touch and can +assist you for free with your Azure migration.

    +

    Links

    + diff --git a/weblogic-azure-aks/src/main/resources/marketing-artifacts/video-thumbnail.png b/weblogic-azure-aks/src/main/resources/marketing-artifacts/video-thumbnail.png new file mode 100644 index 000000000..c10e69547 Binary files /dev/null and b/weblogic-azure-aks/src/main/resources/marketing-artifacts/video-thumbnail.png differ diff --git a/weblogic-azure-aks/src/main/resources/mysql-connector-java.xml b/weblogic-azure-aks/src/main/resources/mysql-connector-java.xml new file mode 100644 index 000000000..4dd31b2af --- /dev/null +++ b/weblogic-azure-aks/src/main/resources/mysql-connector-java.xml @@ -0,0 +1,24 @@ + + + + 4.0.0 + com.oracle.weblogic.azure + mysql-driver + 1.0-SNAPSHOT + jar + + 11 + 11 + + + + + com.mysql + mysql-connector-j + 9.2.0 + + + + \ No newline at end of file diff --git a/weblogic-azure-aks/src/main/resources/weblogic_cpu_images.json b/weblogic-azure-aks/src/main/resources/weblogic_cpu_images.json new file mode 100644 index 000000000..a40c77669 --- /dev/null +++ b/weblogic-azure-aks/src/main/resources/weblogic_cpu_images.json @@ -0,0 +1,46 @@ +{ + "name": "Oracle WebLogic Server docker image tags mapping for Azure Marketplace offer", + "description": "List image tag mapping from Oracle Container Registry middleware/weblogic and middleware/weblogic_cpu repository.", + "items": [ + { + "gaTag": "14.1.2.0-generic-jdk17-ol9", + "cpuTag": "14.1.2.0-generic-jdk17-ol9" + }, + { + "gaTag": "14.1.2.0-generic-jdk21-ol9", + "cpuTag": "14.1.2.0-generic-jdk21-ol9" + }, + { + "gaTag": "14.1.2.0-generic-jdk17-ol8", + "cpuTag": "14.1.2.0-generic-jdk17-ol8" + }, + { + "gaTag": "14.1.2.0-generic-jdk21-ol8", + "cpuTag": "14.1.2.0-generic-jdk21-ol8" + }, + { + "gaTag": "14.1.1.0-11", + "cpuTag": "14.1.1.0-generic-jdk11-ol7" + }, + { + "gaTag": "14.1.1.0-11-ol8", + "cpuTag": "14.1.1.0-generic-jdk11-ol8" + }, + { + "gaTag": "14.1.1.0-8", + "cpuTag": "14.1.1.0-generic-jdk8-ol7" + }, + { + "gaTag": "14.1.1.0-8-ol8", + "cpuTag": "14.1.1.0-generic-jdk8-ol8" + }, + { + "gaTag": "12.2.1.4", + "cpuTag": "12.2.1.4-generic-jdk8-ol7" + }, + { + "gaTag": "12.2.1.4-ol8", + "cpuTag": "12.2.1.4-generic-jdk8-ol8" + } + ] +} diff --git a/weblogic-azure-aks/src/main/resources/weblogic_tooling_family.json b/weblogic-azure-aks/src/main/resources/weblogic_tooling_family.json new file mode 100644 index 000000000..bb8fec93a --- /dev/null +++ b/weblogic-azure-aks/src/main/resources/weblogic_tooling_family.json @@ -0,0 +1,33 @@ +{ + "name": "Oracle WebLogic Server Tooling Family used in WebLogic on AKS offer", + "description": "The versions are known to work for all the features of Azure WebLogic on AKS offer.", + "items": [ + { + "key": "WKO", + "description": "Oracle WebLogic Kubernetes Operator", + "version": "4.1.8", + "testedDate": "2024-03-13" + }, + { + "key": "WDT", + "description": "Oracle WebLogic Deploy Tooling", + "version": "4.3.5", + "downloadURL": "https://github.com/oracle/weblogic-deploy-tooling/releases/download/release-4.3.5/weblogic-deploy.zip", + "testedDate": "2025-05-26" + }, + { + "key": "WIT", + "description": "Oracle WebLogic Image Tool", + "version": "1.15.0", + "downloadURL": "https://github.com/oracle/weblogic-image-tool/releases/download/release-1.15.0/imagetool.zip", + "testedDate": "2025-05-08" + }, + { + "key": "WME", + "description": "Oracle Weblogic Monitoring Exporter. IMPORTANT note to maintener: This value is hard coded in enablePrometheusMetrics.sh. Please update it there also.", + "version": "2.3.0", + "imageURL": "ghcr.io/oracle/weblogic-monitoring-exporter:2.3.0", + "testedDate": "2025-05-08" + } + ] +} diff --git a/weblogic-azure-aks/src/resources/ejb-client-stateless-1.0.0.war b/weblogic-azure-aks/src/resources/ejb-client-stateless-1.0.0.war deleted file mode 100644 index 2028d66b4..000000000 Binary files a/weblogic-azure-aks/src/resources/ejb-client-stateless-1.0.0.war and /dev/null differ diff --git a/weblogic-azure-aks/src/resources/ejb-server-stateless-1.0.0.jar b/weblogic-azure-aks/src/resources/ejb-server-stateless-1.0.0.jar deleted file mode 100644 index 1c2d04522..000000000 Binary files a/weblogic-azure-aks/src/resources/ejb-server-stateless-1.0.0.jar and /dev/null differ diff --git a/weblogic-azure-aks/src/test/genWlsAksParameters.sh b/weblogic-azure-aks/src/test/genWlsAksParameters.sh new file mode 100644 index 000000000..da5bac7e2 --- /dev/null +++ b/weblogic-azure-aks/src/test/genWlsAksParameters.sh @@ -0,0 +1,130 @@ +#!/bin/bash +# Copyright (c) 2023, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +gitUserName=$1 +testbranchName=$2 +appPackageUrls=$3 +dbPassword=$4 +dbUser=$5 +dsConnectionURL=$6 +location=$7 +ocrSSOPSW=$8 +ocrSSOUser=$9 +wdtRuntimePassword=${10} +wlsPassword=${11} +wlsUserName=${12} +vmSize=${13} +parametersPath=${14} + + +cat < ${parametersPath} +{ + "\$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + // This file is used by CI/CD workflows. It allows the workflows to provide parameters when invoking the offer from the command line. + "parameters": { + "_artifactsLocation": { + "value": "https://raw.githubusercontent.com/${gitUserName}/weblogic-azure/${testbranchName}/weblogic-azure-aks/src/main/arm/" + }, + "aksAgentPoolNodeCount": { + "value": 3 + }, + "vmSize": { + "value": "${vmSize}" + }, + "appGatewayCertificateOption": { + "value": "generateCert" + }, + "appgwForAdminServer": { + "value": true + }, + "appgwForRemoteConsole": { + "value": true + }, + "appPackageUrls": { + "value": [ + "${appPackageUrls}" + ] + }, + "appReplicas": { + "value": 2 + }, + "createACR": { + "value": true + }, + "createAKSCluster": { + "value": true + }, + "createDNSZone": { + "value": true + }, + "dbGlobalTranPro": { + "value": "EmulateTwoPhaseCommit" + }, + "dbPassword": { + "value": "${dbPassword}" + }, + "dbUser": { + "value": "${dbUser}" + }, + "databaseType": { + "value": "postgresql" + }, + "dsConnectionURL": { + "value": "${dsConnectionURL}" + }, + "enableAppGWIngress": { + "value": true + }, + "enableAzureMonitoring": { + "value": false + }, + "enableAzureFileShare": { + "value": true + }, + "enableCookieBasedAffinity": { + "value": true + }, + "enableCustomSSL": { + "value": false + }, + "enableDB": { + "value": true + }, + "enableDNSConfiguration": { + "value": false + }, + "jdbcDataSourceName": { + "value": "jdbc/CargoTrackerDB" + }, + "location": { + "value": "${location}" + }, + "ocrSSOPSW": { + "value": "${ocrSSOPSW}" + }, + "ocrSSOUser": { + "value": "${ocrSSOUser}" + }, + "useInternalLB": { + "value": false + }, + "useOracleImage": { + "value": true + }, + "wdtRuntimePassword": { + "value": "${wdtRuntimePassword}" + }, + "wlsImageTag": { + "value": "14.1.1.0-11" + }, + "wlsPassword": { + "value": "${wlsPassword}" + }, + "wlsUserName": { + "value": "${wlsUserName}" + } + } +} +EOF diff --git a/weblogic-azure-aks/src/test/parameters-deploy-template.json b/weblogic-azure-aks/src/test/parameters-deploy-template.json new file mode 100644 index 000000000..5bca0d9c5 --- /dev/null +++ b/weblogic-azure-aks/src/test/parameters-deploy-template.json @@ -0,0 +1,121 @@ +{ + "_artifactsLocation": { + "value": "https://raw.githubusercontent.com/${gitUserName}/weblogic-azure/${testbranchName}/weblogic-azure-aks/src/main/arm/" + }, + "aksAgentPoolNodeCount": { + "value": 3 + }, + "vmSize": { + "value": "${vmSize}" + }, + "appGatewayCertificateOption": { + "value": "generateCert" + }, + "appgwForAdminServer": { + "value": true + }, + "appgwForRemoteConsole": { + "value": true + }, + "appPackageUrls": { + "value": [ + "${appPackageUrls}" + ] + }, + "appReplicas": { + "value": 2 + }, + "createACR": { + "value": true + }, + "createAKSCluster": { + "value": ${createAKSCluster} + }, + "newOrExistingVnetForApplicationGateway": { + "value": "${newOrExistingVnetForApplicationGateway}" + }, + "vnetRGNameForApplicationGateway": { + "value": "${vnetRGNameForApplicationGateway}" + }, + "aksClusterName": { + "value": "${aksClusterName}" + }, + "aksClusterRGName":{ + "value": "${aksClusterRGName}" + }, + "createDNSZone": { + "value": true + }, + "dbGlobalTranPro": { + "value": "EmulateTwoPhaseCommit" + }, + "dbPassword": { + "value": "${dbPassword}" + }, + "dbUser": { + "value": "${dbUser}" + }, + "databaseType": { + "value": "${databaseType}" + }, + "dsConnectionURL": { + "value": "${dsConnectionURL}" + }, + "enablePswlessConnection": { + "value": ${enablePswlessConnection} + }, + "enableAppGWIngress": { + "value": ${enableAppGWIngress} + }, + "enableAzureMonitoring": { + "value": false + }, + "enableAzureFileShare": { + "value": true + }, + "enableCookieBasedAffinity": { + "value": true + }, + "enableCustomSSL": { + "value": false + }, + "enableDB": { + "value": ${enableDB} + }, + "enableDNSConfiguration": { + "value": false + }, + "jdbcDataSourceName": { + "value": "jdbc/CargoTrackerDB" + }, + "location": { + "value": "${location}" + }, + "ocrSSOPSW": { + "value": "${ocrSSOPSW}" + }, + "ocrSSOUser": { + "value": "${ocrSSOUser}" + }, + "useInternalLB": { + "value": false + }, + "useOracleImage": { + "value": true + }, + "wdtRuntimePassword": { + "value": "${wdtRuntimePassword}" + }, + "wlsImageTag": { + "value": "${wlsImageTag}" + }, + "wlsPassword": { + "value": "${wlsPassword}" + }, + "wlsUserName": { + "value": "${wlsUserName}" + }, + "dbIdentity": { + "value": ${dbIdentity} + } +} \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/.github/workflows/build.yml b/weblogic-azure-vm/arm-oraclelinux-wls-admin/.github/workflows/build.yml deleted file mode 100644 index 48bda2b36..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/.github/workflows/build.yml +++ /dev/null @@ -1,523 +0,0 @@ -name: Build and Test - -on: - workflow_dispatch: - inputs: - enableELK: - description: 'Specify whether to enable ELK depoyment or not.' - required: true - default: 'false' - # Allows you to run this workflow using GitHub APIs - # PERSONAL_ACCESS_TOKEN= - # REPO_NAME=wls-eng/arm-oraclelinux-wls-admin - # curl --verbose -XPOST -u "wls-eng:${PERSONAL_ACCESS_TOKEN}" -H "Accept: application/vnd.github.everest-preview+json" -H "Content-Type: application/json" https://api.github.com/repos/${REPO_NAME}/dispatches --data '{"event_type": "production-deploy"}' - repository_dispatch: - -env: - azCliVersion: 2.6.0 - adminConsolePort: 7005 - dbName: wlsdb${{ github.run_id }}${{ github.run_number }} - elkURI: ${{ secrets.ELK_URI }} - elkUser: ${{ secrets.ELK_USER_NAME }} - elkPassword: ${{ secrets.ELK_PSW }} - location: eastus - nsg: wls-nsg - resourceGroupPrefix: wls-${{ github.run_id }}-${{ github.run_number }} - resourceGroupForDependency: wlsd-${{ github.run_id }}-${{ github.run_number }} - userEmail: ${{ secrets.USER_EMAIL }} - userName: ${{ secrets.USER_NAME }} - wlsPassword: ${{ secrets.WLS_PASSWORD }} - adminPassword: ${{ secrets.WLS_PASSWORD }} - wlsDomainName : adminDomain - wlsUserName : weblogic - adminVMName: adminServerVM - offerName: arm-oraclelinux-wls-admin - testbranchName: cicd-${{ github.run_id }}-${{ github.run_number }} - ref_javaee: 6addd99d8bc3f472e040f11c053a37e1ac370229 - ref_armttk: d97aa57d259e2fc8562e11501b1cf902265129d9 - git_token: ${{ secrets.GIT_TOKEN }} - -jobs: - preflight: - runs-on: ubuntu-latest - steps: - - name: Checkout azure-javaee-iaas - uses: actions/checkout@v2 - with: - repository: Azure/azure-javaee-iaas - path: azure-javaee-iaas - ref: ${{ env.ref_javaee }} - - name: Checkout arm-ttk - uses: actions/checkout@v2 - with: - repository: Azure/arm-ttk - path: arm-ttk - ref: ${{ env.ref_armttk }} - - name: Checkout ${{ env.offerName }} - uses: actions/checkout@v2 - with: - path: ${{ env.offerName }} - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 - with: - java-version: 1.8 - - name: Build azure-javaee-iaas - run: mvn -DskipTests clean install --file azure-javaee-iaas/pom.xml - - name: Build and test ${{ env.offerName }} - run: mvn -Ptemplate-validation-tests clean install --file ${{ env.offerName }}/pom.xml - - - name: Checkout ${{ env.offerName }} for test - uses: actions/checkout@v2 - with: - path: ${{ env.offerName }}-dev - - name: Create a new branch with development pids in nestedtemplates - run: | - current=`pwd` - echo "current=${current}" >> $GITHUB_ENV - cd ${{ env.offerName }}-dev/src/main/arm/nestedtemplates - git config --global core.longpaths true - git config --global user.email $userEmail - git config --global user.name $userName - echo "create branch $testbranchName" - git checkout -b $testbranchName - rm -r -f $current/${{ env.offerName }}-dev/src/main/arm/nestedtemplates/* - cp -r -f $current/${{ env.offerName }}/target/arm/nestedtemplates/* $current/${{ env.offerName }}-dev/src/main/arm/nestedtemplates/ - git status - git commit -a -m "hard code pids" - git push https://$git_token@github.com/$userName/${{ env.offerName }}.git -f - - - uses: azure/login@v1 - id: azure-login - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} - - name: Validate deployment templates for different combinations of service integration - id: validate-deployment-templates - run: | - bash ${{ env.offerName }}/test/scripts/verify-deployments.sh \ - <<< "${{ github.run_id }}${{ github.run_number }} ${location} \ - ${{ env.offerName }}/target/arm/mainTemplate.json \ - ${userName} ${testbranchName} ${{ env.offerName }}/test/scripts" - - - name: Get version information from pom.xml - id: version - run: | - version=$(awk '/[^<]+<\/version>/{gsub(/|<\/version>/,"",$1);print $1;exit;}' ${{ env.offerName }}/pom.xml) - echo "version=${version}" >> $GITHUB_ENV - - name: Print version - run: echo $version - - name: Generate artifact name - run: echo "artifactName=${{ env.offerName }}-$version-arm-assembly" >> $GITHUB_ENV - - name: Print artifact name - run: echo $artifactName - - name: Output artifact name - id: artifact_file - run: echo "##[set-output name=artifactName;]${{ env.offerName }}-$version-arm-assembly" - - name: Generate zip package path - id: artifact_path - run: echo "##[set-output name=artifactPath;]${{ env.offerName }}/target/$artifactName" - - name: Output artifact path - run: echo $artifactPath - env: - artifactPath: ${{steps.package.outputs.artifactPath}} - - name: Unzip the package as upload action will zip again - run: unzip ${{ env.offerName }}/target/$artifactName.zip -d ${{ env.offerName }}/target/$artifactName - - - name: Archive ${{ env.offerName }} template - uses: actions/upload-artifact@v1 - if: success() - with: - name: ${{steps.artifact_file.outputs.artifactName}} - path: ${{steps.artifact_path.outputs.artifactPath}} - - deploy-dependencies: - if: ${{!(github.event_name == 'schedule' && github.repository_owner != 'wls-eng')}} - needs: preflight - runs-on: ubuntu-latest - steps: - - uses: azure/login@v1 - id: azure-login - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} - - name: Create Resource Group - id: create-resource-group - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "create resource group" ${{ env.resourceGroupForDependency }} - az group create --verbose --name ${{ env.resourceGroupForDependency }} --location ${location} - - - name: Set Up Azure Postgresql to Test dbTemplate - id: setup-postgresql - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "Deploy DB with name " ${{ env.dbName }} - az postgres server create \ - --resource-group ${{ env.resourceGroupForDependency }} \ - --name ${{ env.dbName }} \ - --location ${location} \ - --admin-user weblogic \ - --ssl-enforcement Enabled \ - --public-network-access Enabled \ - --admin-password ${{ env.wlsPassword }} \ - --sku-name B_Gen5_1 - - echo "Allow Access To Azure Services" - az postgres server firewall-rule create \ - -g ${{ env.resourceGroupForDependency }} \ - -s ${{ env.dbName }} \ - -n "AllowAllWindowsAzureIps" \ - --start-ip-address "0.0.0.0" \ - --end-ip-address "0.0.0.0" - - deploy-weblogic-admin: - if: ${{!(github.event_name == 'schedule' && github.repository_owner != 'wls-eng')}} - needs: deploy-dependencies - runs-on: ubuntu-latest - strategy: - max-parallel: 1 - fail-fast: false - matrix: - images: ["owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest", "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest", "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest", "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest", "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest"] - - steps: - - name: Checkout ${{ env.offerName }} - uses: actions/checkout@v2 - with: - path: ${{ env.offerName }} - - name: Get version information from ${{ env.offerName }}/pom.xml - id: version - run: | - version=$(awk '/[^<]+<\/version>/{gsub(/|<\/version>/,"",$1);print $1;exit;}' ${{ env.offerName }}/pom.xml) - echo "version=${version}" >> $GITHUB_ENV - - name: Output artifact name for Download action - id: artifact_file - run: | - artifactName=${{ env.offerName }}-$version-arm-assembly - echo "artifactName=${artifactName}" >> $GITHUB_ENV - echo "##[set-output name=artifactName;]${artifactName}" - - name: Download artifact for deployment - uses: actions/download-artifact@v1 - with: - name: ${{steps.artifact_file.outputs.artifactName}} - - - uses: azure/login@v1 - id: azure-login - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} - - name: Get Image SKU - id: image-sku - run: | - imageUrn="${{ matrix.images }}" - sku=${imageUrn%%;*} - echo "sku=${sku}" >> $GITHUB_ENV - echo ${resourceGroupPrefix} - resourceGroup=$(echo "${resourceGroupPrefix}-${sku}" | sed "s/_//g") - echo "resourceGroup=${resourceGroup}" >> $GITHUB_ENV - - name: Create Resource Group - id: create-resource-group - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "create resource group" $resourceGroup - az group create --verbose --name $resourceGroup --location ${location} - echo "resourceGroup=${resourceGroup}" >> $GITHUB_ENV - - - name: Prepare deployed parameters and test script - id: prepare-deployed-parameters-and-test-script - run: | - sed -i "s/#location#/$location/g; \ - s/#adminPasswordOrKey#/$wlsPassword/g; \ - s/#wlsdomainname#/$wlsDomainName/g; \ - s/#wlsusername#/$wlsUserName/g; \ - s/#wlspassword#/$wlsPassword/g; \ - s/#adminvmname#/$adminVMName/g; \ - s/#skuUrnVersion#/${{ matrix.images }}/g; \ - s/#testbranchName#/$testbranchName/g; \ - s/#gitUserName#/$userName/g" \ - ${{ env.offerName }}/test/data/parameters-test.json - sed -i "s/#adminPasswordOrKey#/$wlsPassword/g" \ - ${{ env.offerName }}/test/scripts/verify-wls-path.sh - - - name: Accept Image Terms - id: accept-terms - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "accept terms for " "${{ matrix.images }}" - rawUrn="${{ matrix.images }}" - publisherAndName=$(echo ${rawUrn} | grep -o ";.*:" | sed "s/;//g") - imageVersion=${rawUrn##*;} - az vm image terms accept --urn ${publisherAndName}${sku}:${imageVersion} - - - name: Deploy WebLogic Server Admin only Domain offer - id: deploy-wls-admin - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - az deployment group create \ - --verbose \ - --resource-group $resourceGroup \ - --name wls-admin-node \ - --parameters @${{ env.offerName }}/test/data/parameters-test.json \ - --template-file ${{ env.offerName }}-$version-arm-assembly/mainTemplate.json - - - name: Verify Network Security Group - id: verify-nsg - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "query nsg name, will exit with error if nsg does not exist." - az network nsg show -g $resourceGroup -n ${nsg} --query "name" - - - name: Get IP of build machine - id: get-ip-address - run: | - myIP=$(dig @ns1.google.com TXT o-o.myaddr.l.google.com +short) - echo "myIP=${myIP}" >> $GITHUB_ENV - - - name: Add ip address to security rule to access the wls machine - id: add-ip-to-security-rule - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "query existing source address prefixes" - attempt=0 - toCreateRule101=false - while [[ -z `az network nsg show -g $resourceGroup -n ${nsg} | grep "NRMS-Rule-101"` && $attempt -le 5 ]] - do - if [ $attempt -eq 5 ]; then - toCreateRule101=true - fi - echo "network security group rule NRMS-Rule-101 is not ready" - sleep 1m - attempt=$((attempt + 1)) - done - if [ $toCreateRule101 == true ]; then - az network nsg rule create --name NRMS-Rule-101 \ - --nsg-name ${nsg} \ - --priority 101 \ - --resource-group $resourceGroup \ - --access Allow \ - --destination-address-prefixes "*" \ - --destination-port-ranges 22 43 ${adminConsolePort} \ - --direction Inbound \ - --protocol Tcp \ - --source-address-prefixes $myIP - else - sourceAddressPrefixes=$(az network nsg rule show \ - --resource-group $resourceGroup \ - --nsg-name ${nsg} \ - --name NRMS-Rule-101 \ - --query "sourceAddressPrefixes") - echo "IP of this machine: " ${myIP} - sourceAddressPrefixes=$(echo ${myIP} ${sourceAddressPrefixes} | \ - sed 's/,/ /g; s/\[//g; s/\]//g; s/"//g') - echo ${sourceAddressPrefixes} - az network nsg rule update \ - --resource-group $resourceGroup \ - --nsg-name ${nsg} \ - --name NRMS-Rule-101 \ - --source-address-prefixes $sourceAddressPrefixes \ - --destination-port-ranges 443 22 ${adminConsolePort} - fi - - name: Restart wls VM - id: restart-wls-wm - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "restart vm to make sure security rule work." - az vm restart -g $resourceGroup -n $adminVMName - - - name: Query public IP of AdminServer VM - id: query-wls-admin-ip - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "query public ip" - publicIP=$(az vm show \ - --resource-group $resourceGroup \ - --name $adminVMName -d \ - --query publicIps -o tsv) - echo "##[set-output name=publicIP;]${publicIP}" - - name: Create environment variable for AdminServer IP - id: env-admin-ip - run: echo "wlsPublicIP=${{steps.query-wls-admin-ip.outputs.publicIP}}" >> $GITHUB_ENV - - - name: Verify WebLogic Server Installation - id: verify-wls - run: | - echo "pubilc IP of wls machine: ${wlsPublicIP}" - echo "Verifying Weblgic server installation" - timeout 6m sh -c 'until nc -zv $0 $1; do echo "nc rc: $?"; sleep 5; done' ${wlsPublicIP} 22 - echo install sshpass - sudo apt-get install -y sshpass - sshpass -p ${wlsPassword} -v ssh -p 22 -o StrictHostKeyChecking=no -o ConnectTimeout=100 -v -tt weblogic@${wlsPublicIP} 'bash -s' < ${{ env.offerName }}/test/scripts/verify-wls-path.sh - - - name: Restart remote SSH agent - id: restart-remote-ssh - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "Restart remote SSH agent" - az vm user reset-ssh \ - --resource-group $resourceGroup \ - --name ${{ env.adminVMName }} - - - name: Verify system services at admin server - id: veriy-admin-service - run: | - echo "Verifying WebLogic services at admin server" - sshpass -p ${wlsPassword} -v ssh -p 22 -o StrictHostKeyChecking=no -o ConnectTimeout=100 -v -tt weblogic@${wlsPublicIP} 'bash -s' < ${{ env.offerName }}/test/scripts/verify-services.sh - - - name: Verify WebLogic Server Access - id: verify-wls-access - run: | - echo "Verifying Weblogic Server Access" - echo ${wlsPublicIP} - bash ${{ env.offerName }}/test/scripts/verify-wls-access.sh <<< "${wlsPublicIP} 7005" - - - name: Deploy DB Template to Connect to Azure Postgresql Database - id: enable-postgresql-db - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - # Generate parameters for db template deployment - bash ${{ env.offerName }}/test/scripts/gen-parameters-deploy-db.sh \ - <<< "${{ env.offerName }}/test/scripts/ \ - ${{ env.adminVMName }} \ - ${{ env.wlsPassword}} \ - ${{ env.dbName }} \ - ${{ env.location }} \ - ${{ env.wlsUserName }} \ - ${{ env.wlsPassword }} \ - ${{ env.userName }} \ - ${{ env.testbranchName }}" - echo "Deploy DB Template..." - az group deployment create \ - --verbose \ - --resource-group ${resourceGroup} \ - --name db \ - --parameters @${{ env.offerName }}/test/scripts/parameters-deploy-db.json \ - --template-file ${{ env.offerName }}-$version-arm-assembly/nestedtemplates/dbTemplate.json - - - name: Set up ELK by deploying sub template - id: enable-elk - if: ${{github.event_name == 'workflow_dispatch' && github.event.inputs.enableELK == 'true'}} - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - # Generate parameters for ELK template deployment - bash ${{ env.offerName }}/test/scripts/gen-parameters-deploy-elk.sh \ - <<< "${{ env.offerName }}/test/scripts/parameters-deploy-elk.json \ - ${{ env.adminVMName }} \ - ${{ env.elkPassword }} \ - ${{ env.elkURI }} \ - ${{ env.elkUser }} \ - ${{ env.location }} \ - ${{ env.wlsDomainName }} \ - ${{ env.wlsUserName }} \ - ${{ env.wlsPassword }} \ - ${{ env.userName }} \ - ${{ env.testbranchName }} \ - ${{ github.run_id }}${{ github.run_number }}" - echo "Deploy ELK Template..." - az group deployment create \ - --debug \ - --resource-group ${resourceGroup} \ - --name elk \ - --parameters @${{ env.offerName }}/test/scripts/parameters-deploy-elk.json \ - --template-file ${artifactName}/nestedtemplates/elkNestedTemplate.json - - name: Delete Resource Group - id: delete-resource-group - if: always() - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "delete... " $resourceGroup - az group delete --yes --no-wait --verbose --name $resourceGroup - - name: Delete ELK index - id: delete-elk-index - if: ${{github.event_name == 'workflow_dispatch' && github.event.inputs.enableELK == 'true'}} - run: | - curl -XDELETE --user ${{ env.elkUser }}:${{ env.elkPassword }} ${{ env.elkURI }}/azure-weblogic-admin-${{ github.run_id }}${{ github.run_number }} - - cleanup-github-resource: - needs: deploy-weblogic-admin - if: always() - runs-on: ubuntu-latest - steps: - - name: Checkout ${{ env.offerName }} - uses: actions/checkout@v2 - with: - path: ${{ env.offerName }} - - name: Delete testing branch - run: | - cd ${{ env.offerName }} - git push https://$git_token@github.com/$userName/${{ env.offerName }}.git -f --delete $testbranchName - - cleanup-az-resource: - needs: deploy-weblogic-admin - if: always() - runs-on: ubuntu-latest - steps: - - name: Checkout ${{ env.offerName }} - uses: actions/checkout@v2 - if: ${{!(github.event_name == 'schedule' && github.repository_owner != 'wls-eng')}} - with: - path: ${{ env.offerName }} - - uses: azure/login@v1 - if: ${{!(github.event_name == 'schedule' && github.repository_owner != 'wls-eng')}} - id: azure-login - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} - - name: Delete DB Resource Group - id: delete-db-resource-group - uses: azure/CLI@v1 - if: ${{!(github.event_name == 'schedule' && github.repository_owner != 'wls-eng')}} - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "delete... " $resourceGroup - az group delete --yes --no-wait --verbose --name ${{ env.resourceGroupForDependency }} - - summary: - needs: deploy-weblogic-admin - if: always() - runs-on: ubuntu-latest - steps: - - name: summarize jobs - if: ${{!(github.event_name == 'schedule' && github.repository_owner != 'wls-eng')}} - run: | - workflow_jobs=$(curl -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/wls-eng/arm-oraclelinux-wls-admin/actions/runs/${{ github.run_id }}/jobs) - critical_job_num=$(echo $workflow_jobs | jq '.jobs | map(select(.name|test("^deploy-weblogic-admin."))) | length') - echo "$critical_job_num" - succeed_critical_job_num=$(echo $workflow_jobs | jq '.jobs | map(select(.conclusion=="success") | select(.name|test("^deploy-weblogic-admin."))) | length') - echo "$succeed_critical_job_num" - failed_job_num="$(($critical_job_num-$succeed_critical_job_num))" - echo $failed_job_num - if (($failed_job_num >= 2));then - echo "too many jobs failed, send notification to Teams" - curl ${{ secrets.MSTEAMS_WEBHOOK }} \ - -H 'Content-Type: application/json' \ - --data-binary @- << EOF - { - "@context":"http://schema.org/extensions", - "@type":"MessageCard", - "text":"$failed_job_num jobs failed in Admin Offer's workflow, please take a look at: https://github.com/wls-eng/arm-oraclelinux-wls-admin/actions/runs/${{ github.run_id }}" - } - EOF - fi diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/.github/workflows/newtag.yaml b/weblogic-azure-vm/arm-oraclelinux-wls-admin/.github/workflows/newtag.yaml deleted file mode 100644 index 691f75077..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/.github/workflows/newtag.yaml +++ /dev/null @@ -1,110 +0,0 @@ -name: New Tag -on: - workflow_dispatch: - inputs: - tagname: - description: 'Specify Tag name to create/update.' - required: true - default: '2020-12-02-01-Q4' - ref: - description: 'Specify Git Ref if needed.' - required: false - default: 'refs/heads/develop' -env: - tagbranch: "tagbranch" - gitToken: ${{ secrets.GIT_TOKEN }} - refArmttk: d97aa57d259e2fc8562e11501b1cf902265129d9 - refJavaee: 6addd99d8bc3f472e040f11c053a37e1ac370229 - repoName: "arm-oraclelinux-wls-admin" - userEmail: ${{ secrets.USER_EMAIL }} - userName: ${{ secrets.USER_NAME }} - -jobs: - newtag: - runs-on: ubuntu-latest - steps: - - name: Checkout azure-javaee-iaas - uses: actions/checkout@v2 - with: - repository: Azure/azure-javaee-iaas - path: azure-javaee-iaas - ref: ${{ env.refJavaee }} - - name: Checkout arm-ttk - uses: actions/checkout@v2 - with: - repository: Azure/arm-ttk - path: arm-ttk - ref: ${{ env.refArmttk }} - - name: Checkout ${{ env.repoName }} - uses: actions/checkout@v2 - with: - path: ${{ env.repoName }} - ref: ${{ github.event.inputs.ref }} - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 - with: - java-version: 1.8 - - name: Build azure-javaee-iaas - run: mvn -DskipTests clean install --file azure-javaee-iaas/pom.xml - - - name: Build and test ${{ env.repoName }} - run: | - cd ${{ env.repoName }} - mvn -Ptemplate-validation-tests clean install - - - name: Create new tag - run: | - cd ${{ env.repoName }} - git config --global core.longpaths true - git config --global user.email $userEmail - git config --global user.name $userName - - authGitPath=https://$gitToken@github.com/$userName/${{ env.repoName }}.git - - echo "Create tag branch" - remoteBranches=$(git ls-remote --heads) - echo ${remoteBranches} - if [[ -n `echo ${remoteBranches} | grep "${tagbranch}"` ]]; then - git push ${authGitPath} --delete ${tagbranch} -f - fi - - if [[ -n `git branch --all | grep "${tagbranch}"` ]]; then - git branch -D ${tagbranch} - fi - - git checkout -b ${tagbranch} - - # replace pids - export targetARM="arm" - for d in */ ; do - echo $d - if [ ! -d ${d}${targetARM} ];then - continue; - fi - - list=$(find ${d}${targetARM} | grep ".json") - for file in ${list}; do - targetPath=$(echo "$file" | sed "s:target:src/main:g") - if test -f "$targetPath"; then - echo "Replace ${targetPath} with ${file}" - cp -f $file $targetPath - fi - done - done - - git status - git add --all - git commit -m "hard code pids" - git fetch --unshallow - git push ${authGitPath} tagbranch -f - - # remove existing tag - tagname=${{ github.event.inputs.tagname }} - if [[ -n `git ls-remote --tags | grep "${tagname}"` ]]; then - git push ${authGitPath} --delete ${tagname} -f - fi - - # create new tag - git tag ${tagname} - git push ${authGitPath} ${tagname} -f - git push ${authGitPath} --delete ${tagbranch} -f diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/.github/workflows/package.yaml b/weblogic-azure-vm/arm-oraclelinux-wls-admin/.github/workflows/package.yaml deleted file mode 100644 index 521ee1b89..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/.github/workflows/package.yaml +++ /dev/null @@ -1,72 +0,0 @@ -name: Package ARM -on: - workflow_dispatch: - inputs: - pidType: - description: 'Specify which pids to use, oracle or microsoft.' - required: true - default: 'microsoft' - ref: - description: 'Specify Git Ref if needed.' - required: false - default: 'refs/heads/develop' -env: - refArmttk: d97aa57d259e2fc8562e11501b1cf902265129d9 - refJavaee: 6addd99d8bc3f472e040f11c053a37e1ac370229 - repoName: "arm-oraclelinux-wls-admin" - -jobs: - package: - runs-on: ubuntu-latest - steps: - - name: Checkout azure-javaee-iaas - uses: actions/checkout@v2 - with: - repository: Azure/azure-javaee-iaas - path: azure-javaee-iaas - ref: ${{ env.refJavaee }} - - name: Checkout arm-ttk - uses: actions/checkout@v2 - with: - repository: Azure/arm-ttk - path: arm-ttk - ref: ${{ env.refArmttk }} - - name: Checkout ${{ env.repoName }} - uses: actions/checkout@v2 - with: - path: ${{ env.repoName }} - ref: ${{ github.event.inputs.ref }} - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 - with: - java-version: 1.8 - - name: Build azure-javaee-iaas - run: mvn -DskipTests clean install --file azure-javaee-iaas/pom.xml - - - name: Build and test ${{ env.repoName }} using ${{ github.event.inputs.pidType }} pids - run: | - cd ${{ env.repoName }} - pidType=${{ github.event.inputs.pidType }} - if [[ "${pidType}" == "oracle" ]];then - echo "using oracle pid" - mvn -Ptemplate-validation-tests clean install - else - echo "using ms pid" - mvn -Ptemplate-validation-tests clean install -Ddev - fi - - - name: Generate artifact file name and path - id: artifact_file - run: | - version=$(awk '/[^<]+<\/version>/{gsub(/|<\/version>/,"",$1);print $1;exit;}' ${{ env.repoName }}/pom.xml) - artifactName=${{ env.repoName }}-$version-arm-assembly - unzip ${{ env.repoName }}/target/$artifactName.zip -d ${{ env.repoName }}/target/$artifactName - echo "##[set-output name=artifactName;]${artifactName}-${{ github.event.inputs.pidType }}" - echo "##[set-output name=artifactPath;]${{ env.repoName }}/target/$artifactName" - - name: Archive ${{ env.repoName }} template - uses: actions/upload-artifact@v1 - if: success() - with: - name: ${{steps.artifact_file.outputs.artifactName}} - path: ${{steps.artifact_file.outputs.artifactPath}} - diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/README.md b/weblogic-azure-vm/arm-oraclelinux-wls-admin/README.md index 9f98cca02..c4058234a 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/README.md +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/README.md @@ -1,7 +1,11 @@ + + ## WebLogic Server (with Administration Server) on Microsoft Azure - Marketplace Offerings This git repository is used to maintain the Azure Resource Management (ARM) templates and other scripts used for the implementation of WebLogic Server (with Administration Server) on Microsoft Azure. For WebLogic Server running in the Azure Virtual Machines documentation, please refer to the [README documentation](https://github.com/oracle/weblogic-azure/weblogic-azure-vm/arm-oraclelinux-wls/README.md). - diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/admin-ssl-post-deploy/pom.xml b/weblogic-azure-vm/arm-oraclelinux-wls-admin/admin-ssl-post-deploy/pom.xml index ff0b2128a..5698ed0bb 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/admin-ssl-post-deploy/pom.xml +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/admin-ssl-post-deploy/pom.xml @@ -1,36 +1,37 @@ - + 4.0.0 - com.oracle.weblogic.azure - arm-oraclelinux-wls-admin-ssl-config-post-deploy - 1.0.24 - - com.microsoft.azure.iaas - azure-javaee-iaas-parent - 1.0.7 - + com.oracle.weblogic.azure + weblogic-azure-vm + 1.0.0 + ../../pom.xml - + + com.oracle.weblogic.azure + arm-oraclelinux-wls-admin-ssl-config-post-deploy + 1.0.30 + jar ${project.artifactId} - ${basedir}/../../arm-ttk/arm-ttk - -TestParameter '@{"SampleName"="addnode/src/main";"RawRepoPath"="${artifactsLocationBase}/arm-oraclelinux-wls-admin/${git.tag}/"}' - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/pid.properties - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/microsoft-pid.properties + -TestParameter '@{"SampleName"="admin-ssl-post-deploy/src/main";"RawRepoPath"="${artifactsLocationBase}/arm-oraclelinux-wls-admin/"}' + ${project.basedir}/../../.. + false + false - + diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/admin-ssl-post-deploy/src/main/arm/mainTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/admin-ssl-post-deploy/src/main/arm/mainTemplate.json index d59f63ea9..77f835f0b 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/admin-ssl-post-deploy/src/main/arm/mainTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/admin-ssl-post-deploy/src/main/arm/mainTemplate.json @@ -7,7 +7,7 @@ "metadata": { "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." }, - "defaultValue": "${artifactsLocationBase}/arm-oraclelinux-wls-admin/${git.tag}/admin-ssl-post-deploy/src/main/" + "defaultValue": "${artifactsLocationBase}/arm-oraclelinux-wls-admin/admin-ssl-post-deploy/src/main/" }, "_artifactsLocationSasToken": { "type": "securestring", @@ -85,7 +85,6 @@ } }, "variables": { - "const_hyphen": "-", "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", "const_wlsDomainPath": "/u01/domains", "name_scriptFile": "configureCustomAdminSSL.sh" @@ -93,7 +92,7 @@ "resources": [ { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${post.deploy.ssl.config.start}", "properties": { "mode": "Incremental", @@ -107,7 +106,7 @@ { "type": "Microsoft.Compute/virtualMachines/extensions", "name": "[concat(parameters('adminVMName'),'/newuserscript')]", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForVirtualMachines}", "location": "[parameters('location')]", "properties": { "publisher": "Microsoft.Azure.Extensions", @@ -127,7 +126,7 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${post.deploy.ssl.config.end}", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/admin-ssl-post-deploy/src/main/scripts/configureCustomAdminSSL.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/admin-ssl-post-deploy/src/main/scripts/configureCustomAdminSSL.sh index 8679b448f..818498872 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/admin-ssl-post-deploy/src/main/scripts/configureCustomAdminSSL.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/admin-ssl-post-deploy/src/main/scripts/configureCustomAdminSSL.sh @@ -48,9 +48,9 @@ function validateInput() echo_stderr "wlsDomainName is required. " fi - if [[ -z "$wlsUserName" || -z "$wlsPassword" ]] + if [[ -z "$wlsUserName" || -z "$wlsShibboleth" ]] then - echo_stderr "wlsUserName or wlsPassword is required. " + echo_stderr "wlsUserName or wlsShibboleth is required. " exit 1 fi @@ -107,7 +107,7 @@ function configureSSL() isCustomSSLEnabled='${isCustomSSLEnabled}' -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') edit("$wlsServerName") startEdit() cd('/Servers/$wlsServerName') @@ -127,9 +127,13 @@ if isCustomSSLEnabled == 'true' : cmo.setHostnameVerificationIgnored(true) cd('/Servers/$wlsServerName/ServerStart/$wlsServerName') -arguments = '-Dweblogic.Name=$wlsServerName -Dweblogic.security.SSL.ignoreHostnameVerification=true' -cmo.setArguments(arguments) - +arguments = '${SERVER_STARTUP_ARGS} -Dweblogic.Name=$wlsServerName -Dweblogic.security.SSL.ignoreHostnameVerification=true' +oldArgs = cmo.getArguments() +if oldArgs != None: + newArgs = oldArgs + ' ' + arguments +else: + newArgs = arguments +cmo.setArguments(newArgs) save() resolve() activate() @@ -211,14 +215,14 @@ function importAADCertificateIntoWLSCustomTrustKeyStore() exit 1 fi - # For SSL enabled causes AAD failure #225 + # For SSL enabled causes Entra ID failure #225 # ISSUE: https://github.com/wls-eng/arm-oraclelinux-wls/issues/225 - echo "Importing AAD Certificate into WLS Custom Trust Key Store: " + echo "Importing Entra ID Certificate into WLS Custom Trust Key Store: " sudo ${JAVA_HOME}/bin/keytool -noprompt -import -trustcacerts -keystore $customSSLTrustKeyStoreFile -storepass $customTrustKeyStorePassPhrase -alias aadtrust -file ${addsCertificate} -storetype $customTrustKeyStoreType else - echo "customSSL not enabled. Not required to configure AAD for WebLogic Custom SSL" + echo "customSSL not enabled. Not required to configure Entra ID for WebLogic Custom SSL" fi } @@ -287,7 +291,7 @@ args=("$@") ELEMENTS=${#args[@]} #read arguments from stdin -read adminVMName wlsDomainName wlsUserName wlsPassword oracleHome wlsDomainPath enableAAD wlsADSSLCer isCustomSSLEnabled customIdentityKeyStoreBase64String customIdentityKeyStorePassPhrase customIdentityKeyStoreType customTrustKeyStoreBase64String customTrustKeyStorePassPhrase customTrustKeyStoreType privateKeyAlias privateKeyPassPhrase +read adminVMName wlsDomainName wlsUserName wlsShibboleth oracleHome wlsDomainPath enableAAD wlsADSSLCer isCustomSSLEnabled customIdentityKeyStoreBase64String customIdentityKeyStorePassPhrase customIdentityKeyStoreType customTrustKeyStoreBase64String customTrustKeyStorePassPhrase customTrustKeyStoreType privateKeyAlias privateKeyPassPhrase enableAAD="${enableAAD,,}" @@ -301,6 +305,7 @@ username="oracle" groupname="oracle" KEYSTORE_PATH="$wlsDomainPath/$wlsDomainName/keystores" +SERVER_STARTUP_ARGS="-Dlog4j2.formatMsgNoLookups=true" validateInput cleanup diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/cli-scripts/custom-dns-alias-cli.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/cli-scripts/custom-dns-alias-cli.sh index 43bd392fb..a94b8f0ff 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/cli-scripts/custom-dns-alias-cli.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/cli-scripts/custom-dns-alias-cli.sh @@ -22,7 +22,6 @@ Options: -g --resource-group (Required) The name of resource group that has WebLogic cluster deployed -l --location (Required) Location of current cluster resources. -z --zone-name (Required) DNS Zone name - --identity-id (Optional) Specify an Azure Managed User Identity to update DNS Zone --zone-resource-group (Optional) The name of resource group that has WebLogic cluster deployed -h --help @@ -35,7 +34,6 @@ Samples: --artifact-location \\ --location eastus \\ --zone-name contoso.com \\ - --identity-id \\ --zone-resource-group haiche-dns-test1 2. Configure DNS alias on a new DNS Zone @@ -153,14 +151,6 @@ function generateParameterFile() { "hasDNSZones": { "value": ${hasDNSZone} }, - "identity": { - "value": { - "type": "UserAssigned", - "userAssignedIdentities": { - "${identity}": {} - } - } - }, "location": { "value": "${location}" }, @@ -231,7 +221,6 @@ Custom DNS alias: # main script start from here # default value hasDNSZone=false -identity=/subscriptions/subscriptionId/resourceGroups/TestResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/TestUserIdentity1 # Transform long options to short ones for arg in "$@"; do @@ -244,7 +233,6 @@ for arg in "$@"; do "--admin-vm-name") set -- "$@" "-m" ;; "--admin-console-label") set -- "$@" "-c" ;; "--zone-resource-group") set -- "$@" "-r" ;; - "--identity-id") set -- "$@" "-i" ;; "--location") set -- "$@" "-l" ;; "--"*) set -- usage @@ -268,7 +256,6 @@ while getopts "hg:f:z:m:c:w:r:i:l:" opt; do "m") adminVMName="$OPTARG" ;; "c") adminLabel="$OPTARG" ;; "r") zoneResourceGroup="$OPTARG" ;; - "i") identity="$OPTARG" ;; "l") location="$OPTARG" ;; esac done diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/pom.xml b/weblogic-azure-vm/arm-oraclelinux-wls-admin/pom.xml index 5c143d2c3..b792c3082 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/pom.xml +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/pom.xml @@ -1,32 +1,35 @@ - + 4.0.0 - com.oracle.weblogic.azure - arm-oraclelinux-wls-admin - 1.0.25 - - com.microsoft.azure.iaas - azure-javaee-iaas-parent - 1.0.7 - + com.oracle.weblogic.azure + weblogic-azure-vm + 1.0.0 + ../pom.xml - jar + + com.oracle.weblogic.azure + arm-oraclelinux-wls-admin + ${version.arm-oraclelinux-wls-admin} + + pom ${project.artifactId} + - -TestParameter '@{"PasswordMinLength"=5}' - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/pid.properties - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/microsoft-pid.properties + ${project.basedir}/../.. + false + false - - - - + + + admin-ssl-post-deploy + diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/admindeploy.parameters.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/admindeploy.parameters.json index d52f1156c..76353379d 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/admindeploy.parameters.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/admindeploy.parameters.json @@ -2,15 +2,6 @@ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { - "aadsPortNumber": { - "value": "GEN-UNIQUE" - }, - "aadsPublicIP": { - "value": "GEN-UNIQUE" - }, - "aadsServerHost": { - "value": "GEN-UNIQUE" - }, "adminPasswordOrKey": { "value": "GEN-SSH-PUB-KEY" }, @@ -38,39 +29,18 @@ "dsUser": { "value": "GEN-UNIQUE" }, - "enableAAD": { - "value": "GEN-UNIQUE" - }, "enableDB": { "value": "GEN-UNIQUE" }, "jdbcDataSourceName": { "value": "GEN-UNIQUE" }, - "vmSizeSelect": { + "vmSize": { "value": "GEN-UNIQUE" }, "wlsDomainName": { "value": "GEN-UNIQUE" }, - "wlsLDAPProviderName": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPPrincipal": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPPrincipalPassword": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPUserBaseDN": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPGroupBaseDN": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPSSLCertificate": { - "value": "GEN-UNIQUE" - }, "wlsPassword": { "value": "GEN-PASSWORD" }, diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/createUiDefinition.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/createUiDefinition.json index d5fd75fbc..0b231770b 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/createUiDefinition.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/createUiDefinition.json @@ -1,1393 +1,1088 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", - "handler": "Microsoft.Azure.CreateUIDef", - "version": "0.1.2-preview", - "parameters": { - "basics": [ - { - "name": "skuUrnVersion", - "type": "Microsoft.Common.DropDown", - "label": "Oracle WebLogic Image", - "defaultValue": "WebLogic Server 14.1.1.0.0 and JDK11 on Oracle Linux 7.6", - "toolTip": "Choose Oracle WebLogic image, which is provided by Oracle, with Java and WebLogic preinstalled.", - "constraints": { - "allowedValues": [ - { - "label": "WebLogic Server 12.2.1.3.0 and JDK8 on Oracle Linux 7.4", - "value": "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest" - }, - { - "label": "WebLogic Server 12.2.1.3.0 and JDK8 on Oracle Linux 7.3", - "value": "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest" - }, - { - "label": "WebLogic Server 12.2.1.4.0 and JDK8 on Oracle Linux 7.6", - "value": "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest" - }, - { - "label": "WebLogic Server 14.1.1.0.0 and JDK8 on Oracle Linux 7.6", - "value": "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest" - }, - { - "label": "WebLogic Server 14.1.1.0.0 and JDK11 on Oracle Linux 7.6", - "value": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" - } - ], - "required": true - }, - "visible": true - }, - { - "name": "vmSizeSelect", - "type": "Microsoft.Compute.SizeSelector", - "label": "Virtual machine size", - "toolTip": "The size of virtual machine to provision.", - "recommendedSizes": [ - "Standard_A1", - "Standard_A2", - "Standard_A3", - "Standard_A4", - "Standard_B1ms" - ], - "constraints": { - "excludedSizes": [ - "Standard_B1ls", - "Standard_A0", - "Basic_A0", - "Standard_B1s" - ] - }, - "osPlatform": "Linux", - "count": "1", - "visible": true - }, - { - "name": "basicsRequired", - "type": "Microsoft.Common.Section", - "label": "Credentials for Virtual Machines and WebLogic", - "elements": [ - { - "name": "adminUsername", - "type": "Microsoft.Common.TextBox", - "label": "Username for admin account of VMs", - "defaultValue": "weblogic", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - }, - "visible": true - }, - { - "name": "adminPasswordOrKey", - "type": "Microsoft.Compute.CredentialsCombo", - "label": { - "authenticationType": "Authentication type", - "password": "Password", - "confirmPassword": "Confirm password", - "sshPublicKey": "SSH public key" - }, - "toolTip": { - "authenticationType": "Use username and password or SSH public key for authentication to the VM", - "password": "Password for admin account of VMs", - "sshPublicKey": "SSH key for admin account of VMs" - }, - "constraints": { - "required": true, - "customPasswordRegex": "^((?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])|(?=.*[0-9])(?=.*[a-z])(?=.*[!@#$%^&*])|(?=.*[0-9])(?=.*[A-Z])(?=.*[!@#$%^&*])|(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*])).{12,72}$", - "customValidationMessage": "Password must be at least 12 characters long and have 3 out of the following: one number, one lower case, one upper case, or one special character" - }, - "options": { - "hideConfirmation": false, - "hidePassword": false - }, - "osPlatform": "Linux", - "visible": true - }, - { - "name": "wlsUserName", - "type": "Microsoft.Common.TextBox", - "label": "Username for WebLogic Administrator", - "defaultValue": "weblogic", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - }, - "visible": true - }, - { - "name": "wlsPassword", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Password for WebLogic Administrator", - "confirmPassword": "Confirm password" - }, - "toolTip": "Password for WebLogic Administrator", - "constraints": { - "required": true, - "regex": "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)[A-Za-z\\d]{12,}$", - "validationMessage": "The password must contain at least 12 characters, with at least 1 uppercase letter, 1 lowercase letter and 1 number, and special characters are not allowed." - }, - "options": { - "hideConfirmation": false - }, - "visible": true - } - ], - "visible": true - }, - { - "name": "basicsOptional", - "type": "Microsoft.Common.Section", - "label": "Optional Basic Configuration", - "elements": [ - { - "name": "basicsOptionalAcceptDefaults", - "type": "Microsoft.Common.OptionsGroup", - "label": "Accept defaults for optional configuration?", - "defaultValue": "Yes", - "toolTip": "Select 'No' to edit optional basic configuration.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": "false" - }, - { - "label": "No", - "value": "true" - } - ], - "required": true - } - }, - { - "name": "dnsLabelPrefix", - "type": "Microsoft.Common.TextBox", - "label": "DNS Label Prefix", - "toolTip": "The string to prepend to the DNS label.", - "defaultValue": "wls", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{3,10}$", - "validationMessage": "The prefix must be between 3 and 10 characters long and contain letters, numbers only." - }, - "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" - }, - { - "name": "wlsDomainName", - "type": "Microsoft.Common.TextBox", - "label": "WebLogic Domain Name", - "toolTip": "The name of the WebLogic Domain to create.", - "defaultValue": "adminDomain", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{3,20}$", - "validationMessage": "The Domain Name must be between 3 and 20 characters long and contain letters, numbers only." - }, - "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" - }, - { - "name": "portsToExpose", - "label": "Ports and port ranges to expose (N or N-N, comma separated)", - "type": "Microsoft.Common.TextBox", - "toolTip": "Ports and port ranges to expose (N or N-N, comma separated)", - "defaultValue": "80,443,7001-9000", - "constraints": { - "required": true, - "regex": "^((([0-9]+-[0-9]+)|([0-9]+))[,]?)+[^,]$", - "validationMessage": "Only numbers, hyphen separated ranges of numbers, separated by commas" - }, - "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" - }, - { - "name": "denyPublicTrafficForAdminServer", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deny public traffic for admin server?", - "defaultValue": "No", - "toolTip": "Select 'Yes' to deny public traffic for admin server. Configuration here for port 7001 and 7002 has a higher priority than above.", - "constraints": { - "allowedValues": [ - { - "label": "No", - "value": false - }, - { - "label": "Yes", - "value": true - } - ], - "required": true - }, - "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" - }, - { - "name": "enableAdminHTTPListenPort", - "type": "Microsoft.Common.OptionsGroup", - "label": "Enable HTTP listen port on WebLogic Administration Server?", - "defaultValue": "Yes", - "toolTip": "Select 'No' to disable HTTP listen port on WebLogic Administration Server.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": true - }, - { - "label": "No", - "value": false - } - ], - "required": true - }, - "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" - }, - { - "name": "useSystemAssignedManagedIdentity", - "label": "Create a system assigned managed identity to be created for the VM(s).", - "type": "Microsoft.Common.OptionsGroup", - "toolTip": "System assigned managed identities enable credential-free secure access to many Azure resources from this VM.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": true - }, - { - "label": "No", - "value": false - } - ], - "required": true - }, - "defaultValue": "Yes", - "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" - }, - { - "name": "About", - "type": "Microsoft.Common.InfoBox", - "options": { - "icon": "None", - "text": "Template version ${project.version}" - }, - "visible": "[bool('${template.version.visible}')]" - } - ], - "visible": true - }, - { - "name": "howToReportIssues", - "type": "Microsoft.Common.Section", - "label": "Report issues, get help, and share feedback", - "elements": [ - { - "name": "howToReportIssueText", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "If you encounter problems during the deployment of Oracle WebLogic Server, report them here.", - "link": { - "label": "Issue tracker", - "uri": "https://aka.ms/arm-oraclelinux-wls-issues" - } - } - }, - { - "name": "howToJoinSlack", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "If you want to interact directly with the Oracle WebLogic community, join the public Slack channel named 'oracle-weblogic'.", - "link": { - "label": "Join Slack", - "uri": "https://aka.ms/arm-oraclelinux-wls-slack" - } - } - }, - { - "name": "survey", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "To get free help with Azure migration from the development team, fill out this survey.", - "link": { - "label": "Take survey", - "uri": "https://aka.ms/wls-on-azure-survey" - } - } - } - ], - "visible": true - } - ], - "steps": [ - { - "name": "section_sslConfiguration", - "type": "Microsoft.Common.Section", - "label": "TLS/SSL Configuration", - "elements": [ - { - "name": "sslConfigurationText", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "Selecting 'Yes' here will cause the template to provision WebLogic Administration Console on HTTPS (Secure) port, with your own TLS/SSL certificate.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-ssl-config" - } - } - }, - { - "name": "enableCustomSSL", - "type": "Microsoft.Common.OptionsGroup", - "label": "Configure WebLogic Administration Console on HTTPS (Secure) port, with your own TLS/SSL certificate?", - "defaultValue": "No", - "toolTip": "Select 'Yes' to configure WebLogic Administration Console on HTTPS (Secure) port with your own TLS/SSL certificate.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": true - }, - { - "label": "No", - "value": false - } - ], - "required": false - } - }, - { - "name": "sslConfigurationAccessOption", - "type": "Microsoft.Common.OptionsGroup", - "visible": "[steps('section_sslConfiguration').enableCustomSSL]", - "label": "How would you like to provide required configuration", - "defaultValue": "Upload existing KeyStores", - "toolTip": "Select 'Upload existing KeyStores' to use local stored KeyStores.", - "constraints": { - "allowedValues": [ - { - "label": "Upload existing KeyStores", - "value": "uploadConfig" - }, - { - "label": "Use KeyStores stored in Azure Key Vault", - "value": "keyVaultStoredConfig" - } - ], - "required": false - } - }, - { - "name": "uploadedCustomSSLSettings", - "type": "Microsoft.Common.Section", - "visible": "[and(steps('section_sslConfiguration').enableCustomSSL, equals(steps('section_sslConfiguration').sslConfigurationAccessOption, 'uploadConfig'))]", - "label": "TLS/SSL Configuration Settings", - "elements": [ - { - "name": "sslKeystoreInfo0", - "type": "Microsoft.Common.InfoBox", - "visible": "true", - "options": { - "icon": "Info", - "text": "You must provide different files for identity and trust KeyStores. Select here for more details.", - "uri": "https://aka.ms/arm-oraclelinux-wls-ssl-configuration" - } - }, - { - "name": "uploadedCustomIdentityKeyStoreData", - "type": "Microsoft.Common.FileUpload", - "label": "Identity KeyStore Data file(.jks,.p12)", - "toolTip": "Identity KeyStore for TLS/SSL configuration", - "constraints": { - "required": true, - "accept": ".jks,.p12" - }, - "options": { - "multiple": false, - "uploadMode": "file", - "openMode": "binary" - }, - "visible": true - }, - { - "name": "uploadedCustomIdentityKeyStorePassphrase", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Password", - "confirmPassword": "Confirm password" - }, - "toolTip": " The passphrase for the Identity KeyStore", - "constraints": { - "required": true, - "regex": "^.{6,}$", - "validationMessage": "Keypass must be at least 6 characters long." - }, - "options": { - "hideConfirmation": false - }, - "visible": true - }, - { - "name": "uploadedCustomIdentityKeyStoreType", - "type": "Microsoft.Common.DropDown", - "visible": "true", - "label": "The Identity KeyStore type (JKS,PKCS12)", - "defaultValue": "JKS", - "toolTip": "One of the supported KeyStore types", - "constraints": { - "allowedValues": [ - { - "label": "JKS", - "value": "JKS" - }, - { - "label": "PKCS12", - "value": "PKCS12" - } - ], - "required": true - } - }, - { - "name": "uploadedPrivateKeyAlias", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The alias of the server's private key within the Identity KeyStore", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "uploadedPrivateKeyPassPhrase", - "type": "Microsoft.Common.PasswordBox", - "visible": "true", - "label": { - "password": "The passphrase for the server's private key within the Identity KeyStore", - "confirmPassword": "Confirm passphrase" - }, - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^.{6,}$", - "validationMessage": "Keypass must be at least 6 characters long." - }, - "options": { - "hideConfirmation": false - } - }, - { - "name": "uploadedCustomTrustKeyStoreData", - "type": "Microsoft.Common.FileUpload", - "label": "Trust KeyStore Data file(.jks,.p12)", - "toolTip": "Trust KeyStore for TLS/SSL configuration.", - "constraints": { - "required": true, - "accept": ".jks,.p12" - }, - "options": { - "multiple": false, - "uploadMode": "file", - "openMode": "binary" - }, - "visible": true - }, - { - "name": "uploadedCustomTrustKeyStorePassPhrase", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Password", - "confirmPassword": "Confirm password" - }, - "toolTip": " The passphrase for the Trust KeyStore", - "constraints": { - "required": true, - "regex": "^.{6,}$", - "validationMessage": "Keypass must be at least 6 characters long." - }, - "options": { - "hideConfirmation": false - }, - "visible": true - }, - { - "name": "uploadedCustomTrustKeyStoreType", - "type": "Microsoft.Common.DropDown", - "visible": "true", - "label": "The Trust KeyStore type (JKS,PKCS12)", - "defaultValue": "JKS", - "toolTip": "One of the supported KeyStore types", - "constraints": { - "allowedValues": [ - { - "label": "JKS", - "value": "JKS" - }, - { - "label": "PKCS12", - "value": "PKCS12" - } - ], - "required": true - } - } - ] - }, - { - "name": "keyVaultStoredCustomSSLSettings", - "type": "Microsoft.Common.Section", - "visible": "[and(steps('section_sslConfiguration').enableCustomSSL, equals(steps('section_sslConfiguration').sslConfigurationAccessOption, 'keyVaultStoredConfig'))]", - "label": "TLS/SSL Configuration Settings", - "elements": [ - { - "name": "sslKeystoreInfo1", - "type": "Microsoft.Common.InfoBox", - "visible": "true", - "options": { - "icon": "Info", - "text": "You must provide different files for identity and trust KeyStores. Select here for more details.", - "uri": "https://aka.ms/arm-oraclelinux-wls-ssl-configuration" - } - }, - { - "name": "keyVaultText", - "type": "Microsoft.Common.TextBlock", - "visible": "true", - "options": { - "text": "Enabling a HTTPS (Secure) port for the Administration Console requires you to obtain a valid TLS/SSL certificate. The template will look for the certificate and other configuration items in the Azure Key Vault specified here.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-cluster-app-gateway-key-vault" - } - } - }, - { - "name": "keyVaultResourceGroup", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "Resource group name in current subscription containing the Key Vault", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1})$", - "validationMessage": "[if(greater(length(steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultResourceGroup), 90),'Resource group names only allow up to 90 characters.', 'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" - } - }, - { - "name": "keyVaultName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "Name of the Azure Key Vault containing secrets for the TLS/SSL certificate", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^(?=.{3,24}$)[a-zA-Z](([a-z0-9A-Z]*|(?:\\-[^\\-][a-z0-9A-Z]*))*)$", - "validationMessage": "[if(or(greater(length(steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultName), 24), less(length(steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultName), 3)),'Vault name must be between 3-24 alphanumeric characters. The name must begin with a letter, end with a letter or digit, and not contain consecutive hyphens.','Vault name must only contain alphanumeric characters and dashes and cannot start with a number')]" - } - }, - { - "name": "keyVaultCustomIdentityKeyStoreDataSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the Identity KeyStore Data", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "keyVaultCustomIdentityKeyStorePassPhraseSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the passphrase for the Identity KeyStore", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "keyVaultCustomIdentityKeyStoreType", - "type": "Microsoft.Common.DropDown", - "visible": "true", - "label": "The Identity KeyStore type (JKS,PKCS12)", - "defaultValue": "JKS", - "toolTip": "One of the supported KeyStore types", - "constraints": { - "allowedValues": [ - { - "label": "JKS", - "value": "JKS" - }, - { - "label": "PKCS12", - "value": "PKCS12" - } - ], - "required": true - } - }, - { - "name": "keyVaultPrivateKeyAliasSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the Private Key Alias", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "keyVaultPrivateKeyPassPhraseSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the passphrase for the Private Key", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "keyVaultCustomTrustKeyStoreDataSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the Trust KeyStore Data", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "keyVaultCustomTrustKeyStorePassPhraseSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the passphrase for the Trust KeyStore", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "keyVaultCustomTrustKeyStoreType", - "type": "Microsoft.Common.DropDown", - "visible": "true", - "label": "The Trust KeyStore type (JKS,PKCS12)", - "defaultValue": "JKS", - "toolTip": "One of the supported KeyStore types", - "constraints": { - "allowedValues": [ - { - "label": "JKS", - "value": "JKS" - }, - { - "label": "PKCS12", - "value": "PKCS12" - } - ], - "required": true - } - } - ] - } - ] - }, - { - "name": "section_dnsConfiguration", - "type": "Microsoft.Common.Section", - "label": "DNS Configuration", - "elements": [ - { - "name": "dnsConfigurationText", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "Selecting 'Yes' here will cause the template to provision Oracle WebLogic Server Administration Console using custom DNS Name (example: admin.contoso.com)", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-dns" - } - } - }, - { - "name": "enableCustomDNS", - "type": "Microsoft.Common.OptionsGroup", - "visible": true, - "label": "Configure Custom DNS Alias?", - "defaultValue": "No", - "toolTip": "Select 'Yes' to configure Custom DNS Alias.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": true - }, - { - "label": "No", - "value": false - } - ], - "required": false - } - }, - { - "name": "customDNSSettings", - "type": "Microsoft.Common.Section", - "label": "DNS Configuration Settings", - "visible": "[bool(steps('section_dnsConfiguration').enableCustomDNS)]", - "elements": [ - { - "name": "bringDNSZone", - "type": "Microsoft.Common.OptionsGroup", - "label": "Use an existing Azure DNS Zone", - "defaultValue": "No", - "toolTip": "Select 'Yes' to configure Custom DNS Alias based on an existing Azure DNS Zone. Select 'No' to create an Azure DNS Zone and Custom DNS Alias.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": true - }, - { - "label": "No", - "value": false - } - ] - } - }, - { - "name": "createDNSZoneText", - "type": "Microsoft.Common.InfoBox", - "visible": "[not(bool(steps('section_dnsConfiguration').customDNSSettings.bringDNSZone))]", - "options": { - "icon": "Info", - "text": "You must perform DNS Domain Delegation at your DNS Registry after deployment.", - "uri": "https://aka.ms/dns-domain-delegation" - } - }, - { - "name": "deplymentScriptInfo", - "type": "Microsoft.Common.TextBlock", - "options": { - "text": "If you choose to use an existing Azure DNS Zone, you must select a user-assigned managed identity to enable the necessary configuration." - }, - "visible": "[steps('section_dnsConfiguration').customDNSSettings.bringDNSZone]" - }, - { - "name": "dnszoneName", - "type": "Microsoft.Common.TextBox", - "label": "DNS Zone Name", - "defaultValue": "", - "toolTip": "Use only letters and numbers and periods to separate Domains", - "constraints": { - "required": true, - "regex": "^([0-9a-zA-Z_-]{1,63}\\.){1,33}[0-9a-zA-Z_-]{1,63}$", - "validationMessage": "There must be between 2 and 34 labels. For example, \"contoso.com\" has 2 labels. Each label must contain between 1 and 63 characters. Each label must only contain letters, numbers, underscores, and dashes." - } - }, - { - "name": "dnsZoneResourceGroup", - "type": "Microsoft.Common.TextBox", - "label": "Name of the resource group which contains the DNS Zone in current subscription", - "defaultValue": "", - "toolTip": "Name of the resource group which contains the DNS Zone in current subscription", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1})$", - "validationMessage": "[if(greater(length(steps('section_dnsConfiguration').existingDNSZonesSettings.dnsZoneResourceGroup), 90),'Resource group names only allow up to 90 characters.', 'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" - }, - "visible": "[steps('section_dnsConfiguration').customDNSSettings.bringDNSZone]" - }, - { - "name": "dnszoneAdminConsoleLabel", - "type": "Microsoft.Common.TextBox", - "label": "Label for Oracle WebLogic Administration Console", - "defaultValue": "admin", - "toolTip": "Specify a label to generate subdomain of Oracle WebLogic Administration Console", - "constraints": { - "required": true, - "validations": [ - { - "regex": "^([0-9a-zA-Z_-]{1,63}\\.){0,33}[0-9a-zA-Z_-]{1,63}$", - "message": "Each label must contain between 1 and 63 characters. Each label must only contain letters, numbers, underscores, and dashes." - }, - { - "isValid": "[less(sub(length(concat(steps('section_dnsConfiguration').customDNSSettings.dnszoneAdminConsoleLabel,'.',steps('section_dnsConfiguration').customDNSSettings.dnszoneName)),length(replace(concat(steps('section_dnsConfiguration').customDNSSettings.dnszoneAdminConsoleLabel,'.',steps('section_dnsConfiguration').customDNSSettings.dnszoneName), '.', ''))),34)]", - "message": "Subdomain must be between 2 and 34 labels. For example, \"admin.contoso.com\" has 3 labels." - } - ] - } - }, - { - "name": "infoDNSIndentity", - "type": "Microsoft.Common.InfoBox", - "visible": "[and(steps('section_dnsConfiguration').customDNSSettings.bringDNSZone, less(length(steps('section_dnsConfiguration').customDNSSettings.dnsIdentity.userAssignedIdentities), 1))]", - "options": { - "icon": "Error", - "text": "This option will use Azure deployment scripts to update records to your Azure DNS Zone. You have to add at least one user-assigned identity to access Azure resources.", - "uri": "https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/deployment-script-template" - } - }, - { - "name": "dnsIdentity", - "type": "Microsoft.ManagedIdentity.IdentitySelector", - "label": "Managed Identity Configuration", - "toolTip": { - "userAssignedIdentity": "Add user-assigned identities to grant the resource access to Azure resources." - }, - "defaultValue": { - "systemAssignedIdentity": "Off" - }, - "options": { - "hideSystemAssignedIdentity": true, - "hideUserAssignedIdentity": false - }, - "visible": "[steps('section_dnsConfiguration').customDNSSettings.bringDNSZone]" - } - ] - } - ] - }, - { - "name": "section_database", - "type": "Microsoft.Common.Section", - "label": "Database", - "subLabel": { - "preValidation": "Configure integrations to database", - "postValidation": "Done" - }, - "bladeTitle": "Database", - "elements": [ - { - "name": "aboutDatabase", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "Selecting 'Yes' here and providing the configuration will cause the template to configure the WebLogic Server to connect to the desired pre-existing database. The database must be network accessible to the VNET and subnets created by the template." - } - }, - { - "name": "enableDB", - "type": "Microsoft.Common.OptionsGroup", - "label": "Connect to database?", - "defaultValue": "No", - "toolTip": "Select 'Yes' and provide required info to configure the connection to a database.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": "true" - }, - { - "label": "No", - "value": "false" - } - ], - "required": true - } - }, - { - "name": "databaseConnectionInfo", - "type": "Microsoft.Common.Section", - "label": "Connection settings", - "elements": [ - { - "name": "databaseType", - "type": "Microsoft.Common.DropDown", - "label": "Choose database type", - "toolTip": "Choose database type", - "defaultValue": "Oracle database", - "constraints": { - "allowedValues": [ - { - "label": "Azure database for PostgreSQL", - "value": "postgresql" - }, - { - "label": "Oracle database", - "value": "oracle" - }, - { - "label": "Azure SQL", - "value": "sqlserver" - } - ], - "required": true - }, - "visible": true - }, - { - "name": "jdbcDataSourceName", - "type": "Microsoft.Common.TextBox", - "label": "JNDI Name", - "toolTip": "The JNDI name for the database JDBC connection", - "defaultValue": "", - "constraints": { - "required": "[bool(steps('section_database').enableDB)]", - "regex": "^[a-z0-9A-Z/]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters, numbers, and slashes (/)." - }, - "visible": true - }, - { - "name": "dsConnectionURL", - "type": "Microsoft.Common.TextBox", - "label": "DataSource Connection String", - "toolTip": "The JDBC connection string for the database", - "defaultValue": "", - "constraints": { - "required": "[bool(steps('section_database').enableDB)]", - "regex": "[concat('^jdbc:', coalesce(steps('section_database').databaseConnectionInfo.databaseType, ''), '.*$')]", - "validationMessage": "A valid JDBC URL for the chosen database type must be provided" - }, - "visible": true - }, - { - "name": "dbUser", - "type": "Microsoft.Common.TextBox", - "label": "Database username", - "toolTip": "Use only letters and numbers", - "defaultValue": "", - "constraints": { - "required": "[bool(steps('section_database').enableDB)]", - "regex": "^(?!\\-)([a-z0-9A-Z@\\-]{1,128})([^\\-])$", - "validationMessage": "The value must be 1-128 characters long and must only contain letters, numbers, hyphen(-) and the at sign, no hyphen allowed at the beginning and the end of database username." - }, - "visible": true - }, - { - "name": "dbPassword", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Database Password", - "confirmPassword": "Confirm password" - }, - "toolTip": "Database Password", - "constraints": { - "required": "[bool(steps('section_database').enableDB)]", - "regex": "^((?=.*[0-9])(?=.*[a-zA-Z!@#$%^&*])).{5,128}$", - "validationMessage": "The password must be between five and 128 characters long and have at least one number." - }, - "options": { - "hideConfirmation": false - }, - "visible": true - } - ], - "visible": "[bool(steps('section_database').enableDB)]" - } - ] - }, - { - "name": "section_aad", - "label": "Azure Active Directory", - "subLabel": { - "preValidation": "Configure the connection to Azure Active Directory.", - "postValidation": "Done" - }, - "bladeTitle": "Azure Active Directory", - "elements": [ - { - "name": "aboutAad", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "icon": "None", - "text": "Selecting 'Yes' here and providing the configuration will cause the template to configure the connection to Azure Active Directory.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-cluster-aad-ldap" - } - } - }, - { - "name": "enableAAD", - "type": "Microsoft.Common.OptionsGroup", - "label": "Connect to Azure Active Directory?", - "defaultValue": "No", - "toolTip": "Select 'Yes' and provide required info to configure the connection to Azure Active Directory.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": "true" - }, - { - "label": "No", - "value": "false" - } - ], - "required": true - } - }, - { - "name": "aadInfo", - "type": "Microsoft.Common.Section", - "label": "Connection settings", - "elements": [ - { - "name": "aadsServerHost", - "type": "Microsoft.Common.TextBox", - "label": "Server Host", - "toolTip": "The LDAP server host.", - "defaultValue": "", - "constraints": { - "required": true, - "regex": "(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]", - "validationMessage": "The value must be a valid host name." - } - }, - { - "name": "aadsPublicIP", - "type": "Microsoft.Common.TextBox", - "label": "Secure LDAP external IP address", - "toolTip": "Secure LDAP external IP address.", - "constraints": { - "required": true, - "regex": "\\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.|$)){4}\\b", - "validationMessage": "The value must be a valid IP address." - } - }, - { - "name": "aadsPortNumber", - "type": "Microsoft.Common.TextBox", - "label": "Port", - "toolTip": "The port number of LDAP Server, default is 636.", - "defaultValue": "636", - "constraints": { - "required": true, - "regex": "^[0-9]+$", - "validationMessage": "The value must be numbers." - } - }, - { - "name": "wlsLDAPProviderName", - "type": "Microsoft.Common.TextBox", - "label": "Provider Name", - "defaultValue": "AzureActiveDirectoryProvider", - "toolTip": "The value used for creating authentication provider name of WebLogic Server.", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{3,50}$", - "validationMessage": "The Provider Name must be between 3 and 50 characters long and contain letters, numbers only." - } - }, - { - "name": "wlsLDAPPrincipal", - "type": "Microsoft.Common.TextBox", - "label": "Principal", - "toolTip": "The Distinguished Name (DN) of the LDAP user that WebLogic Server should use to connect to the LDAP server.", - "constraints": { - "required": true, - "regex": ".+,dc|DC=([^,]+),dc|DC=([^,]+)$", - "validationMessage": "The value must be valid LDAP user distinguished name." - } - }, - { - "name": "wlsLDAPPrincipalPassword", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Password for Principal", - "confirmPassword": "Confirm password" - }, - "toolTip": "The credential (usually a password) used to connect to the LDAP server.", - "constraints": { - "required": true - } - }, - { - "name": "wlsLDAPUserBaseDN", - "type": "Microsoft.Common.TextBox", - "label": "User Base DN", - "toolTip": "The base distinguished name (DN) of the tree in the LDAP directory that contains users.", - "constraints": { - "required": true, - "regex": ".+,dc|DC=([^,]+),dc|DC=([^,]+)$", - "validationMessage": "The value must be valid LDAP user based distinguished name." - } - }, - { - "name": "wlsLDAPGroupBaseDN", - "type": "Microsoft.Common.TextBox", - "label": "Group Base DN", - "toolTip": "The base distinguished name (DN) of the tree in the LDAP directory that contains groups.", - "constraints": { - "required": true, - "regex": ".+,dc|DC=([^,]+),dc|DC=([^,]+)$", - "validationMessage": "The value must be valid LDAP group based distinguished name." - } - }, - { - "name": "wlsLDAPSSLCertificate", - "type": "Microsoft.Common.FileUpload", - "label": "Client certificate for TLS/SSL Configuration (.cer)", - "toolTip": "Client certificate of AAD LADP server, used to configure the Trust Keystore to enable TLS/SSL in Oracle WebLogic Server.", - "constraints": { - "required": true, - "accept": ".cer" - }, - "options": { - "multiple": false, - "uploadMode": "file", - "openMode": "binary" - } - } - ], - "visible": "[bool(steps('section_aad').enableAAD)]" - } - ] - }, - { - "name": "section_elk", - "label": "Elasticsearch and Kibana", - "subLabel": { - "preValidation": "Configure the connection to Elasticsearch and Kibana.", - "postValidation": "Done" - }, - "bladeTitle": "Elasticsearch and Kibana", - "elements": [ - { - "name": "aboutelk", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "icon": "None", - "text": "Selecting 'Yes' here and providing the configuration will cause the template to configure Elasticsearch and Kibana to store WLS logs.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-elk-tutorial" - } - } - }, - { - "name": "enableELK", - "type": "Microsoft.Common.OptionsGroup", - "label": "Export logs to Elasticsearch server?", - "defaultValue": "No", - "toolTip": "Select 'Yes' and provide required info to configure the connection to Elasticsearch.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": "true" - }, - { - "label": "No", - "value": "false" - } - ], - "required": true - } - }, - { - "name": "elkInfo", - "type": "Microsoft.Common.Section", - "label": "Connection settings", - "elements": [ - { - "name": "elkMemoryRequiredText", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "icon": "None", - "text": "To ensure Logstash works correctly, the selected Virtual Machines have at least 2.5GB memory.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-elk" - } - } - }, - { - "name": "elkMemoryRequired", - "type": "Microsoft.Common.InfoBox", - "options": { - "icon": "Error", - "text": "Your selected Virtual Machines have less than 2.5GB memory to set up Elasticsearch and Kibana, please go to Basics -> Virtual machine size to change it, recommended size is Standard_A2_v2." - }, - "visible": "[and(contains('Standard_A1,Basic_A1,Standard_B1ms,Standard_A1_v2,Standard_F1,Standard_F1s', basics('vmSizeSelect')),bool(steps('section_elk').enableELK))]" - }, - { - "name": "elasticsearchEndpoint", - "type": "Microsoft.Common.TextBox", - "label": "Elasticsearch endpoint URL", - "toolTip": "Elasticsearch endpoint.", - "defaultValue": "https://example.location.azure.elastic-cloud.com:9243", - "constraints": { - "required": true, - "validations": [ - { - "regex": "^https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*):[0-9]{1,6}$", - "message": "The value must be a valid uri." - }, - { - "isValid": "[not(contains('Standard_A1,Basic_A1,Standard_B1ms,Standard_A1_v2,Standard_F1,Standard_F1s', basics('vmSizeSelect')))]", - "message": "Your selected Virtual Machines have less than 2.5GB memory to set up Elasticsearch and Kibana, please go to Basics -> Virtual machine size to change it, recommended size is Standard_A2_v2." - } - ] - } - }, - { - "name": "elasticsearchUserName", - "type": "Microsoft.Common.TextBox", - "label": "Elasticsearch User Name", - "defaultValue": "elastic", - "toolTip": "User name of Elasticsearch account.", - "constraints": { - "required": true, - "regex": "^(?!\\-)([a-z0-9A-Z@\\-]{1,128})([^\\-])", - "validationMessage": "The value must be valid Elasticsearch user name." - } - }, - { - "name": "elasticsearchPassword", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Password for Elasticsearch account", - "confirmPassword": "Confirm password" - }, - "toolTip": "Password for Elasticsearch account.", - "constraints": { - "required": true - } - }, - { - "name": "logsToIntegrate", - "type": "Microsoft.Common.DropDown", - "label": "WebLogic Server logs to export", - "toolTip": "The logs selected will be exported to Elasticsearch.", - "defaultValue": [ - "Server Log" - ], - "multiselect": true, - "selectAll": true, - "multiLine": true, - "defaultDescription": "The logs selected will be exported to Elasticsearch", - "constraints": { - "allowedValues": [ - { - "label": "Data Source Log", - "description": "Export Datasource logs to Elasticsearch.", - "value": "DataSourceLog" - }, - { - "label": "Domain Log", - "description": "Export Domain logs to Elasticsearch.", - "value": "DomainLog" - }, - { - "label": "HTTP Access Log", - "description": "Export HTTP logs to Elasticsearch.", - "value": "HTTPAccessLog" - }, - { - "label": "Server Log", - "description": "Export Server logs to Elasticsearch.", - "value": "ServerLog" - }, - { - "label": "Standard error and output", - "description": "Export standard error and output to Elasticsearch.", - "value": "StandardErrorAndOutput" - } - ], - "required": true - } - } - ], - "visible": "[bool(steps('section_elk').enableELK)]" - } - ] - } - ], - "outputs": { - "Location": "[location()]", - "aadsPortNumber": "[steps('section_aad').aadInfo.aadsPortNumber]", - "aadsPublicIP": "[steps('section_aad').aadInfo.aadsPublicIP]", - "aadsServerHost": "[steps('section_aad').aadInfo.aadsServerHost]", - "adminPasswordOrKey": "[if(equals(basics('basicsRequired').adminPasswordOrKey.authenticationType, 'password'), basics('basicsRequired').adminPasswordOrKey.password, basics('basicsRequired').adminPasswordOrKey.sshPublicKey)]", - "adminUsername": "[basics('basicsRequired').adminUsername]", - "authenticationType": "[basics('basicsRequired').adminPasswordOrKey.authenticationType]", - "databaseType": "[steps('section_database').databaseConnectionInfo.databaseType]", - "denyPublicTrafficForAdminServer": "[basics('basicsOptional').denyPublicTrafficForAdminServer]", - "dbPassword": "[steps('section_database').databaseConnectionInfo.dbPassword]", - "dbUser": "[steps('section_database').databaseConnectionInfo.dbUser]", - "dnsLabelPrefix": "[basics('basicsOptional').dnsLabelPrefix]", - "dnszoneIdentity": "[steps('section_dnsConfiguration').customDNSSettings.dnsIdentity]", - "dnszoneName": "[steps('section_dnsConfiguration').customDNSSettings.dnszoneName]", - "dnszoneResourceGroup": "[steps('section_dnsConfiguration').customDNSSettings.dnsZoneResourceGroup]", - "dnszoneAdminConsoleLabel": "[steps('section_dnsConfiguration').customDNSSettings.dnszoneAdminConsoleLabel]", - "dsConnectionURL": "[steps('section_database').databaseConnectionInfo.dsConnectionURL]", - "elasticsearchEndpoint": "[steps('section_elk').elkInfo.elasticsearchEndpoint]", - "elasticsearchPassword": "[steps('section_elk').elkInfo.elasticsearchPassword]", - "elasticsearchUserName": "[steps('section_elk').elkInfo.elasticsearchUserName]", - "enableAAD": "[bool(steps('section_aad').enableAAD)]", - "enableDB": "[bool(steps('section_database').enableDB)]", - "enableCustomDNS": "[bool(steps('section_dnsConfiguration').enableCustomDNS)]", - "enableELK": "[bool(steps('section_elk').enableELK)]", - "hasDNSZones": "[bool(if(bool(steps('section_dnsConfiguration').enableCustomDNS), steps('section_dnsConfiguration').customDNSSettings.bringDNSZone, 'false'))]", - "jdbcDataSourceName": "[steps('section_database').databaseConnectionInfo.jdbcDataSourceName]", - "logsToIntegrate": "[steps('section_elk').elkInfo.logsToIntegrate]", - "portsToExpose": "[basics('basicsOptional').portsToExpose]", - "skuUrnVersion": "[basics('skuUrnVersion')]", - "useSystemAssignedManagedIdentity": "[basics('basicsOptional').useSystemAssignedManagedIdentity]", - "vmSizeSelect": "[basics('vmSizeSelect')]", - "wlsDomainName": "[basics('basicsOptional').wlsDomainName]", - "wlsLDAPGroupBaseDN": "[steps('section_aad').aadInfo.wlsLDAPGroupBaseDN]", - "wlsLDAPPrincipal": "[steps('section_aad').aadInfo.wlsLDAPPrincipal]", - "wlsLDAPPrincipalPassword": "[steps('section_aad').aadInfo.wlsLDAPPrincipalPassword]", - "wlsLDAPProviderName": "[steps('section_aad').aadInfo.wlsLDAPProviderName]", - "wlsLDAPSSLCertificate": "[steps('section_aad').aadInfo.wlsLDAPSSLCertificate]", - "wlsLDAPUserBaseDN": "[steps('section_aad').aadInfo.wlsLDAPUserBaseDN]", - "wlsPassword": "[basics('basicsRequired').wlsPassword]", - "wlsUserName": "[basics('basicsRequired').wlsUserName]", - "enableHTTPAdminListenPort": "[basics('basicsOptional').enableAdminHTTPListenPort]", - "enableCustomSSL": "[steps('section_sslConfiguration').enableCustomSSL]", - "sslConfigurationAccessOption": "[steps('section_sslConfiguration').sslConfigurationAccessOption]", - "adminSSLKeyVaultResourceGroup": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultResourceGroup]", - "adminSSLKeyVaultName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultName]", - "keyVaultCustomIdentityKeyStoreDataSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomIdentityKeyStoreDataSecretName]", - "keyVaultCustomIdentityKeyStorePassPhraseSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomIdentityKeyStorePassPhraseSecretName]", - "keyVaultCustomIdentityKeyStoreType": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomIdentityKeyStoreType]", - "keyVaultCustomTrustKeyStoreDataSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomTrustKeyStoreDataSecretName]", - "keyVaultCustomTrustKeyStorePassPhraseSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomTrustKeyStorePassPhraseSecretName]", - "keyVaultCustomTrustKeyStoreType": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomTrustKeyStoreType]", - "keyVaultPrivateKeyAliasSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultPrivateKeyAliasSecretName]", - "keyVaultPrivateKeyPassPhraseSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultPrivateKeyPassPhraseSecretName]", - "uploadedCustomIdentityKeyStoreData": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomIdentityKeyStoreData]", - "uploadedCustomIdentityKeyStorePassphrase": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomIdentityKeyStorePassphrase]", - "uploadedCustomIdentityKeyStoreType": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomIdentityKeyStoreType]", - "uploadedCustomTrustKeyStoreData": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomTrustKeyStoreData]", - "uploadedCustomTrustKeyStorePassPhrase": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomTrustKeyStorePassPhrase]", - "uploadedCustomTrustKeyStoreType": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomTrustKeyStoreType]", - "uploadedPrivateKeyAlias": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedPrivateKeyAlias]", - "uploadedPrivateKeyPassPhrase": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedPrivateKeyPassPhrase]" - } - } -} +{ + "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", + "handler": "Microsoft.Azure.CreateUIDef", + "version": "0.1.2-preview", + "parameters": { + "config": { + "basics": { + "resourceGroup": { + "allowExisting": true + } + } + }, + "basics": [ + { + "name": "skuUrnVersion", + "type": "Microsoft.Common.DropDown", + "label": "Oracle WebLogic Image", + "defaultValue": "WebLogic Server 14.1.2.0.0 and JDK 21 on Oracle Linux 9", + "toolTip": "Choose Oracle WebLogic image, which is provided by Oracle, with Java and WebLogic preinstalled.", + "constraints": { + "allowedValues": [ + { + "label": "WebLogic Server 14.1.2.0.0 and JDK 21 on Oracle Linux 9", + "value": "owls-141200-jdk21-ol94;Oracle:weblogic-141200-jdk21-ol94:owls-141200-jdk21-ol94;latest" + }, + { + "label": "WebLogic Server 14.1.2.0.0 and JDK 21 on Oracle Linux 8", + "value": "owls-141200-jdk21-ol810;Oracle:weblogic-141200-jdk21-ol810:owls-141200-jdk21-ol810;latest" + }, + { + "label": "WebLogic Server 14.1.2.0.0 and JDK 17 on Oracle Linux 9", + "value": "owls-141200-jdk17-ol94;Oracle:weblogic-141200-jdk17-ol94:owls-141200-jdk17-ol94;latest" + }, + { + "label": "WebLogic Server 14.1.2.0.0 and JDK 17 on Oracle Linux 8", + "value": "owls-141200-jdk17-ol810;Oracle:weblogic-141200-jdk17-ol810:owls-141200-jdk17-ol810;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK 11 on Oracle Linux 9", + "value": "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK 11 on Oracle Linux 8", + "value": "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK 8 on Oracle Linux 9", + "value": "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK 8 on Oracle Linux 8", + "value": "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest" + }, + { + "label": "WebLogic Server 12.2.1.4.0 and JDK 8 on Oracle Linux 9", + "value": "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest" + }, + { + "label": "WebLogic Server 12.2.1.4.0 and JDK 8 on Oracle Linux 8", + "value": "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK11 on Red Hat Enterprise Linux 8", + "value": "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK8 on Red Hat Enterprise Linux 8", + "value": "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest" + }, + { + "label": "WebLogic Server 12.2.1.4.0 and JDK8 on Red Hat Enterprise Linux 8", + "value": "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest" + } + ], + "required": true + }, + "visible": true + }, + { + "name": "vmSizeSelect", + "type": "Microsoft.Compute.SizeSelector", + "label": "Virtual machine size", + "toolTip": "The size of virtual machine to provision.", + "recommendedSizes": [ + "Standard_A1", + "Standard_A2", + "Standard_A3", + "Standard_A4", + "Standard_B1ms" + ], + "constraints": { + "excludedSizes": [ + "Standard_B1ls", + "Standard_A0", + "Basic_A0", + "Standard_B1s", + ${azure.armBased.vmSize.list} + ] + }, + "osPlatform": "Linux", + "count": "1", + "visible": true + }, + { + "name": "invalidVMSizeInfo", + "type": "Microsoft.Common.InfoBox", + "visible": "[contains(basics('vmSizeSelect'),'p')]", + "options": { + "icon": "Error", + "text": "The VM size you selected includes the feature letter 'p', indicating it uses ARM CPUs. ARM platform is not supported. Please select a different VM size. For more information, refer to the Azure virtual machine sizes naming conventions." + } + }, + { + "name": "basicsRequired", + "type": "Microsoft.Common.Section", + "label": "Credentials for Virtual Machines and WebLogic", + "elements": [ + { + "name": "adminUsername", + "type": "Microsoft.Common.TextBox", + "label": "Username for admin account of VMs", + "defaultValue": "weblogic", + "toolTip": "Use only letters and numbers", + "constraints": { + "required": true, + "validations": [ + { + "regex": "^[a-z0-9A-Z]{1,30}$", + "message": "The value must be 1-30 characters long and must only contain letters and numbers." + }, + { + "isValid": "[not(contains(basics('vmSizeSelect'),'p'))]", + "message": "ARM platform is not supported. Please select a different VM size." + } + ] + }, + "visible": true + }, + { + "name": "adminPasswordOrKey", + "type": "Microsoft.Compute.CredentialsCombo", + "label": { + "authenticationType": "Authentication type", + "password": "Password", + "confirmPassword": "Confirm password", + "sshPublicKey": "SSH public key" + }, + "toolTip": { + "authenticationType": "Use username and password or SSH public key for authentication to the VM", + "password": "Password for admin account of VMs", + "sshPublicKey": "SSH key for admin account of VMs" + }, + "constraints": { + "required": true, + "customPasswordRegex": "^((?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])|(?=.*[0-9])(?=.*[a-z])(?=.*[!@#$%^&*])|(?=.*[0-9])(?=.*[A-Z])(?=.*[!@#$%^&*])|(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*])).{12,72}$", + "customValidationMessage": "Password must be at least 12 characters long and have 3 out of the following: one number, one lower case, one upper case, or one special character" + }, + "options": { + "hideConfirmation": false, + "hidePassword": false + }, + "osPlatform": "Linux", + "visible": true + }, + { + "name": "wlsUserName", + "type": "Microsoft.Common.TextBox", + "label": "Username for WebLogic Administrator", + "defaultValue": "weblogic", + "toolTip": "Use only letters and numbers", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{1,30}$", + "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." + }, + "visible": true + }, + { + "name": "wlsPassword", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Password for WebLogic Administrator", + "confirmPassword": "Confirm password" + }, + "toolTip": "Password for WebLogic Administrator", + "constraints": { + "required": true, + "regex": "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)[A-Za-z\\d]{12,}$", + "validationMessage": "The password must contain at least 12 characters, with at least 1 uppercase letter, 1 lowercase letter and 1 number, and special characters are not allowed." + }, + "options": { + "hideConfirmation": false + }, + "visible": true + } + ], + "visible": true + }, + { + "name": "basicsOptional", + "type": "Microsoft.Common.Section", + "label": "Optional Basic Configuration", + "elements": [ + { + "name": "basicsOptionalAcceptDefaults", + "type": "Microsoft.Common.OptionsGroup", + "label": "Accept defaults for optional configuration?", + "defaultValue": "Yes", + "toolTip": "Select 'No' to edit optional basic configuration.", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": "false" + }, + { + "label": "No", + "value": "true" + } + ], + "required": true + } + }, + { + "name": "wlsDomainName", + "type": "Microsoft.Common.TextBox", + "label": "WebLogic Domain Name", + "toolTip": "The name of the WebLogic Domain to create.", + "defaultValue": "adminDomain", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{3,20}$", + "validationMessage": "The Domain Name must be between 3 and 20 characters long and contain letters, numbers only." + }, + "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" + }, + { + "name": "enableAdminHTTPListenPort", + "type": "Microsoft.Common.OptionsGroup", + "label": "Enable HTTP listen port on WebLogic Administration Server?", + "defaultValue": "Yes", + "toolTip": "Select 'No' to disable HTTP listen port on WebLogic Administration Server.", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": true + }, + { + "label": "No", + "value": false + } + ], + "required": true + }, + "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" + }, + { + "name": "useSystemAssignedManagedIdentity", + "label": "Create a system assigned managed identity to be created for the VM(s).", + "type": "Microsoft.Common.OptionsGroup", + "toolTip": "System assigned managed identities enable credential-free secure access to many Azure resources from this VM.", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": true + }, + { + "label": "No", + "value": false + } + ], + "required": true + }, + "defaultValue": "Yes", + "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" + } + ], + "visible": true + }, + { + "name": "howToReportIssues", + "type": "Microsoft.Common.Section", + "label": "Report issues, get help, and share feedback", + "elements": [ + { + "name": "help", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "See the documentation for this offer.", + "link": { + "label": "Offer documentation", + "uri": "https://aka.ms/wls-vm-docs" + } + } + }, + { + "name": "howToReportIssueText", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "If you encounter problems during the deployment of Oracle WebLogic Server, report them here.", + "link": { + "label": "Issue tracker", + "uri": "https://aka.ms/arm-oraclelinux-wls-issues?version=${project.version}" + } + } + }, + { + "name": "howToJoinSlack", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "If you want to interact directly with the Oracle WebLogic community, join the public Slack channel named 'oracle-weblogic'.", + "link": { + "label": "Join Slack", + "uri": "https://aka.ms/arm-oraclelinux-wls-slack" + } + } + }, + { + "name": "survey", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "To get free help with Azure migration from the development team, fill out this survey.", + "link": { + "label": "Take survey", + "uri": "https://aka.ms/wls-on-azure-survey" + } + } + } + ], + "visible": true + } + ], + "steps": [ + { + "name": "section_sslConfiguration", + "type": "Microsoft.Common.Section", + "label": "TLS/SSL Configuration", + "elements": [ + { + "name": "sslConfigurationText", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "Selecting 'Yes' here will cause the template to provision WebLogic Administration Console on HTTPS (Secure) port, with your own TLS/SSL certificate.", + "link": { + "label": "Learn more", + "uri": "https://aka.ms/arm-oraclelinux-wls-ssl-config" + } + } + }, + { + "name": "enableCustomSSL", + "type": "Microsoft.Common.OptionsGroup", + "label": "Configure WebLogic Administration Console on HTTPS (Secure) port, with your own TLS/SSL certificate?", + "defaultValue": "No", + "toolTip": "Select 'Yes' to configure WebLogic Administration Console on HTTPS (Secure) port with your own TLS/SSL certificate.", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": true + }, + { + "label": "No", + "value": false + } + ], + "required": false + } + }, + { + "name": "uploadedCustomSSLSettings", + "type": "Microsoft.Common.Section", + "visible": "[steps('section_sslConfiguration').enableCustomSSL]", + "label": "TLS/SSL Configuration Settings", + "elements": [ + { + "name": "sslKeystoreInfo0", + "type": "Microsoft.Common.InfoBox", + "visible": "true", + "options": { + "icon": "Info", + "text": "You must provide different files for identity and trust KeyStores. Select here for more details.", + "uri": "https://aka.ms/arm-oraclelinux-wls-ssl-configuration" + } + }, + { + "name": "uploadedCustomIdentityKeyStoreData", + "type": "Microsoft.Common.FileUpload", + "label": "Identity KeyStore Data file(.jks,.p12)", + "toolTip": "Identity KeyStore for TLS/SSL configuration", + "constraints": { + "required": true, + "accept": ".jks,.p12" + }, + "options": { + "multiple": false, + "uploadMode": "file", + "openMode": "binary" + }, + "visible": true + }, + { + "name": "uploadedCustomIdentityKeyStorePassphrase", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Password", + "confirmPassword": "Confirm password" + }, + "toolTip": " The passphrase for the Identity KeyStore", + "constraints": { + "required": true, + "regex": "^.{6,}$", + "validationMessage": "Keypass must be at least 6 characters long." + }, + "options": { + "hideConfirmation": false + }, + "visible": true + }, + { + "name": "uploadedCustomIdentityKeyStoreType", + "type": "Microsoft.Common.DropDown", + "visible": "true", + "label": "The Identity KeyStore type (JKS,PKCS12)", + "defaultValue": "JKS", + "toolTip": "One of the supported KeyStore types", + "constraints": { + "allowedValues": [ + { + "label": "JKS", + "value": "JKS" + }, + { + "label": "PKCS12", + "value": "PKCS12" + } + ], + "required": true + } + }, + { + "name": "uploadedPrivateKeyAlias", + "type": "Microsoft.Common.TextBox", + "visible": "true", + "label": "The alias of the server's private key within the Identity KeyStore", + "defaultValue": "", + "toolTip": "Use only letters and numbers", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{1,30}$", + "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." + } + }, + { + "name": "uploadedPrivateKeyPassPhrase", + "type": "Microsoft.Common.PasswordBox", + "visible": "true", + "label": { + "password": "The passphrase for the server's private key within the Identity KeyStore", + "confirmPassword": "Confirm passphrase" + }, + "toolTip": "Use only letters and numbers", + "constraints": { + "required": true, + "regex": "^.{6,}$", + "validationMessage": "Keypass must be at least 6 characters long." + }, + "options": { + "hideConfirmation": false + } + }, + { + "name": "uploadedCustomTrustKeyStoreData", + "type": "Microsoft.Common.FileUpload", + "label": "Trust KeyStore Data file(.jks,.p12)", + "toolTip": "Trust KeyStore for TLS/SSL configuration.", + "constraints": { + "required": true, + "accept": ".jks,.p12" + }, + "options": { + "multiple": false, + "uploadMode": "file", + "openMode": "binary" + }, + "visible": true + }, + { + "name": "uploadedCustomTrustKeyStorePassPhrase", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Password", + "confirmPassword": "Confirm password" + }, + "toolTip": " The passphrase for the Trust KeyStore", + "constraints": { + "required": true, + "regex": "^.{6,}$", + "validationMessage": "Keypass must be at least 6 characters long." + }, + "options": { + "hideConfirmation": false + }, + "visible": true + }, + { + "name": "uploadedCustomTrustKeyStoreType", + "type": "Microsoft.Common.DropDown", + "visible": "true", + "label": "The Trust KeyStore type (JKS,PKCS12)", + "defaultValue": "JKS", + "toolTip": "One of the supported KeyStore types", + "constraints": { + "allowedValues": [ + { + "label": "JKS", + "value": "JKS" + }, + { + "label": "PKCS12", + "value": "PKCS12" + } + ], + "required": true + } + } + ] + } + ] + }, + { + "name": "section_networkingConfiguration", + "type": "Microsoft.Common.Section", + "label": "Networking", + "elements": [ + { + "name": "vnetInfo", + "type": "Microsoft.Common.InfoBox", + "options": { + "icon": "Info", + "text": "When creating a new virtual network, the subnet's address prefix is calculated automatically based on the virtual
    network's address prefix. When using an existing virtual network, a minimum virtual network size of /28 and a
    minimum subnet size of /29 are required. Additionally, the subnet must have adequate available addresses for
    the server setup." + } + }, + { + "name": "virtualNetwork", + "type": "Microsoft.Network.VirtualNetworkCombo", + "label": { + "virtualNetwork": "Virtual network", + "subnets": "Subnets" + }, + "toolTip": { + "virtualNetwork": "Name of the virtual network", + "subnets": "Subnets for the virtual network" + }, + "defaultValue": { + "name": "[concat('wlsadmin-vnet',take(guid(), 8))]", + "addressPrefixSize": "/28" + }, + "constraints": { + "minAddressPrefixSize": "/28" + }, + "subnets": { + "subnet1": { + "label": "Subnet", + "defaultValue": { + "name": "Subnet-1", + "addressPrefixSize": "/29" + }, + "constraints": { + "minAddressPrefixSize": "/29", + "minAddressCount": 2, + "requireContiguousAddresses": false + } + } + } + }, + { + "name": "denyPublicTrafficForAdminServer", + "type": "Microsoft.Common.OptionsGroup", + "visible": "[equals(steps('section_networkingConfiguration').virtualNetwork.newOrExisting, 'new')]", + "label": "Deny public traffic for admin server?", + "defaultValue": "No", + "toolTip": "Select 'Yes' to deny public traffic for admin server. Configuration here for port 7001 and 7002 has a higher priority than above.", + "constraints": { + "allowedValues": [ + { + "label": "No", + "value": false + }, + { + "label": "Yes", + "value": true + } + ], + "required": true + } + }, + { + "name": "dnsConfigurationText", + "type": "Microsoft.Common.TextBlock", + "visible": "[equals(steps('section_networkingConfiguration').virtualNetwork.newOrExisting, 'new')]", + "options": { + "text": "Selecting 'Yes' here will cause the template to provision Oracle WebLogic Server Administration Console using custom DNS Name (example: admin.contoso.com)", + "link": { + "label": "Learn more", + "uri": "https://aka.ms/arm-oraclelinux-wls-dns" + } + } + }, + { + "name": "enableCustomDNS", + "type": "Microsoft.Common.OptionsGroup", + "visible": "[equals(steps('section_networkingConfiguration').virtualNetwork.newOrExisting, 'new')]", + "label": "Configure Custom DNS Alias?", + "defaultValue": "No", + "toolTip": "Select 'Yes' to configure Custom DNS Alias.", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": true + }, + { + "label": "No", + "value": false + } + ], + "required": false + } + }, + { + "name": "dnsLabelPrefix", + "type": "Microsoft.Common.TextBox", + "label": "DNS Label Prefix", + "toolTip": "The string to prepend to the DNS label.", + "defaultValue": "wls", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{3,10}$", + "validationMessage": "The prefix must be between 3 and 10 characters long and contain letters, numbers only." + }, + "visible": "[bool(steps('section_networkingConfiguration').enableCustomDNS)]" + }, + { + "name": "portsToExpose", + "label": "Ports and port ranges to expose (N or N-N, comma separated)", + "type": "Microsoft.Common.TextBox", + "toolTip": "Ports and port ranges to expose (N or N-N, comma separated)", + "defaultValue": "80,443,7001-9000", + "constraints": { + "required": true, + "regex": "^((([0-9]+-[0-9]+)|([0-9]+))[,]?)+[^,]$", + "validationMessage": "Only numbers, hyphen separated ranges of numbers, separated by commas" + }, + "visible": "[bool(steps('section_networkingConfiguration').enableCustomDNS)]" + }, + { + "name": "customDNSSettings", + "type": "Microsoft.Common.Section", + "label": "DNS Configuration Settings", + "visible": "[bool(steps('section_networkingConfiguration').enableCustomDNS)]", + "elements": [ + { + "name": "bringDNSZone", + "type": "Microsoft.Common.OptionsGroup", + "label": "Use an existing Azure DNS Zone", + "defaultValue": "No", + "toolTip": "Select 'Yes' to configure Custom DNS Alias based on an existing Azure DNS Zone. Select 'No' to create an Azure DNS Zone and Custom DNS Alias.", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": true + }, + { + "label": "No", + "value": false + } + ] + } + }, + { + "name": "createDNSZoneText", + "type": "Microsoft.Common.InfoBox", + "visible": "[not(bool(steps('section_networkingConfiguration').customDNSSettings.bringDNSZone))]", + "options": { + "icon": "Info", + "text": "You must perform DNS Domain Delegation at your DNS Registry after deployment.", + "uri": "https://aka.ms/dns-domain-delegation" + } + }, + { + "name": "createDNSZonePublicResolveWarning", + "type": "Microsoft.Common.InfoBox", + "visible": "[bool(steps('section_networkingConfiguration').customDNSSettings.bringDNSZone)]", + "options": { + "icon": "Info", + "text": "The referenced hostnames must be publicly resolvable before deployment.", + "uri": "https://learn.microsoft.com/en-us/azure/dns/dns-getstarted-portal" + } + }, + { + "name": "infoDNSIndentity", + "type": "Microsoft.Common.InfoBox", + "visible": "[steps('section_networkingConfiguration').customDNSSettings.bringDNSZone]", + "options": { + "icon": "Info", + "text": "This option will add/update records in your Azure DNS Zone.The Azure identity deploying this feature must have one of the following two sets of Azure role-based access control roles:
  • Contributor and User Access Administrator of the current subscription.
  • Owner of the current subscription.
  • " + } + }, + { + "name": "dnszoneName", + "type": "Microsoft.Common.TextBox", + "label": "DNS Zone Name", + "defaultValue": "", + "toolTip": "Use only letters and numbers and periods to separate Domains", + "constraints": { + "required": true, + "regex": "^([0-9a-zA-Z_-]{1,63}\\.){1,33}[0-9a-zA-Z_-]{1,63}$", + "validationMessage": "There must be between 2 and 34 labels. For example, \"contoso.com\" has 2 labels. Each label must contain between 1 and 63 characters. Each label must only contain letters, numbers, underscores, and dashes." + } + }, + { + "name": "dnsZoneResourceGroup", + "type": "Microsoft.Common.TextBox", + "label": "Name of the resource group which contains the DNS Zone in current subscription", + "defaultValue": "", + "toolTip": "Name of the resource group which contains the DNS Zone in current subscription", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1})$", + "validationMessage": "[if(greater(length(steps('section_networkingConfiguration').existingDNSZonesSettings.dnsZoneResourceGroup), 90),'Resource group names only allow up to 90 characters.', 'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" + }, + "visible": "[steps('section_networkingConfiguration').customDNSSettings.bringDNSZone]" + }, + { + "name": "dnszoneAdminConsoleLabel", + "type": "Microsoft.Common.TextBox", + "label": "Label for Oracle WebLogic Administration Console", + "defaultValue": "admin", + "toolTip": "Specify a label to generate subdomain of Oracle WebLogic Administration Console", + "constraints": { + "required": true, + "validations": [ + { + "regex": "^([0-9a-zA-Z_-]{1,63}\\.){0,33}[0-9a-zA-Z_-]{1,63}$", + "message": "Each label must contain between 1 and 63 characters. Each label must only contain letters, numbers, underscores, and dashes." + }, + { + "isValid": "[less(sub(length(concat(steps('section_networkingConfiguration').customDNSSettings.dnszoneAdminConsoleLabel,'.',steps('section_networkingConfiguration').customDNSSettings.dnszoneName)),length(replace(concat(steps('section_networkingConfiguration').customDNSSettings.dnszoneAdminConsoleLabel,'.',steps('section_networkingConfiguration').customDNSSettings.dnszoneName), '.', ''))),34)]", + "message": "Subdomain must be between 2 and 34 labels. For example, \"admin.contoso.com\" has 3 labels." + } + ] + } + } + ] + } + ] + }, + { + "name": "section_database", + "type": "Microsoft.Common.Section", + "label": "Database", + "subLabel": { + "preValidation": "Configure integrations to database", + "postValidation": "Done" + }, + "bladeTitle": "Database", + "elements": [ + { + "name": "aboutDatabase", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "Selecting 'Yes' here and providing the configuration will cause the template to configure the WebLogic Server to connect to the desired pre-existing database. The database must be network accessible to the VNET and subnets created by the template." + } + }, + { + "name": "enableDB", + "type": "Microsoft.Common.OptionsGroup", + "label": "Connect to database?", + "defaultValue": "No", + "toolTip": "Select 'Yes' and provide required info to configure the connection to a database.", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": "true" + }, + { + "label": "No", + "value": "false" + } + ], + "required": true + } + }, + { + "name": "databaseConnectionInfo", + "type": "Microsoft.Common.Section", + "label": "Connection settings", + "elements": [ + { + "name": "databaseType", + "type": "Microsoft.Common.DropDown", + "label": "Choose database type", + "toolTip": "Choose database type", + "defaultValue": "Oracle database", + "constraints": { + "allowedValues": [ + { + "label": "PostgreSQL (Supports passwordless connection)", + "value": "postgresql" + }, + { + "label": "Oracle database", + "value": "oracle" + }, + { + "label": "Microsoft SQL Server (Supports passwordless connection)", + "value": "sqlserver" + }, + { + "label": "MySQL (Supports passwordless connection)", + "value": "mysql" + } + ], + "required": true + }, + "visible": true + }, + { + "name": "mysqlJDBCDriverInfo", + "type": "Microsoft.Common.InfoBox", + "visible": "[and(bool(steps('section_database').enableDB),equals(steps('section_database').databaseConnectionInfo.databaseType, 'mysql'))]", + "options": { + "icon": "Info", + "text": "To support passwordless connection and various functionalities, the offer will upgrade the
    Oracle WebLogic Server MySQL driver with recent MySQL Connector Java driver." + } + }, + { + "name": "jdbcDataSourceName", + "type": "Microsoft.Common.TextBox", + "label": "JNDI Name", + "toolTip": "The JNDI name for the database JDBC connection", + "defaultValue": "", + "constraints": { + "required": true, + "validations": [ + { + "regex": "^[a-z0-9A-Z/]{1,30}$", + "message": "The value must be 1-30 characters long and must only contain letters, numbers, and slashes (/)." + } + ] + }, + "visible": true + }, + { + "name": "dsConnectionURL", + "type": "Microsoft.Common.TextBox", + "label": "DataSource Connection String", + "toolTip": "The JDBC connection string for the database", + "defaultValue": "", + "constraints": { + "required": true, + "validations": [ + { + "regex": "^jdbc:.*$", + "message": "A valid JDBC URL must start with 'jdbc:'." + }, + { + "isValid": "[startsWith(steps('section_database').databaseConnectionInfo.dsConnectionURL, concat('jdbc:', steps('section_database').databaseConnectionInfo.databaseType))]", + "message": "A valid JDBC URL for the chosen database type must be provided." + }, + { + "isValid": "[if(and(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection), equals(steps('section_database').databaseConnectionInfo.databaseType, 'mysql')), and(not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'defaultAuthenticationPlugin')),not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'authenticationPlugins')), not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'azure.clientId'))), 'true')]", + "message": "The offer will append defaultAuthenticationPlugin, authenticationPlugins with Azure provided plugins, and append azure.clientId with your managed identity client ID automatically, please do not specify them in your connection string." + }, + { + "isValid": "[if(and(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection), equals(steps('section_database').databaseConnectionInfo.databaseType, 'postgresql')), and(not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'authenticationPluginClassName')),not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'azure.clientId'))), 'true')]", + "message": "The offer will append authenticationPluginClassName with Azure provided plugins, and append azure.clientId with your managed identity client ID automatically, please do not specify them in your connection string." + }, + { + "isValid": "[if(and(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection), equals(steps('section_database').databaseConnectionInfo.databaseType, 'sqlserver')), and(not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'authentication=ActiveDirectoryMSI')),not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'msiClientId'))), 'true')]", + "message": "The offer will append authentication with ActiveDirectoryMSI, and append msiClientId with your managed identity client ID automatically, please do not specify them in your connection string." + }, + { + "isValid": "[if(and(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection0),equals(steps('section_database').databaseConnectionInfo.databaseType, 'sqlserver')), greater(length(steps('section_database').databaseConnectionInfo.dbIdentity.userAssignedIdentities),0), bool('true'))]", + "message": "You must select at least one managed identity that has access to your database." + } + ] + }, + "visible": true + }, + { + "name": "dbGlobalTranPro", + "type": "Microsoft.Common.DropDown", + "label": "Global transactions protocol", + "defaultValue": "OnePhaseCommit", + "multiLine": true, + "toolTip": "Determines the transaction protocol (global transaction processing behavior) for the data source.", + "constraints": { + "allowedValues": [ + { + "label": "TwoPhaseCommit", + "description": "Standard XA transaction processing. Requires an XA driver.", + "value": "TwoPhaseCommit" + }, + { + "label": "LoggingLastResource", + "description": "A performance enhancement for one non-XA resource.", + "value": "LoggingLastResource" + }, + { + "label": "EmulateTwoPhaseCommit", + "description": "Enables one non-XA resource to participate in a global transaction, but has some risk to data.", + "value": "EmulateTwoPhaseCommit" + }, + { + "label": "OnePhaseCommit", + "description": "One-phase XA transaction processing using a non-XA driver. This is the default setting.", + "value": "OnePhaseCommit" + }, + { + "label": "None", + "description": "Support for local transactions only.", + "value": "None" + } + ], + "required": true + }, + "visible": true + }, + { + "name": "enablePswlessConnection0", + "type": "Microsoft.Common.CheckBox", + "label": "Use passwordless datasource connection", + "toolTip": "Use passwordless datasource connection.", + "visible": "[and(bool(steps('section_database').enableDB),equals(steps('section_database').databaseConnectionInfo.databaseType, 'sqlserver'))]" + }, + { + "name": "dbUser", + "type": "Microsoft.Common.TextBox", + "label": "Database username", + "toolTip": "Use only letters and numbers", + "defaultValue": "", + "constraints": { + "required": true, + "validations": [ + { + "regex": "^(?!\\-)([a-z0-9A-Z@\\-]{1,128})([^\\-])$", + "message": "The value must be 1-128 characters long and must only contain letters, numbers, hyphen(-) and the at sign, no hyphen allowed at the beginning and the end of database username." + }, + { + "isValid": "[if(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection), greater(length(steps('section_database').databaseConnectionInfo.dbIdentity.userAssignedIdentities),0), bool('true'))]", + "message": "You must select at least one managed identity that has access to your database." + } + ] + }, + "visible": "[and(bool(steps('section_database').enableDB), not(and(steps('section_database').databaseConnectionInfo.enablePswlessConnection0, equals(steps('section_database').databaseConnectionInfo.databaseType, 'sqlserver'))))]" + }, + { + "name": "enablePswlessConnection", + "type": "Microsoft.Common.CheckBox", + "label": "Use passwordless datasource connection", + "toolTip": "Use passwordless datasource connection.", + "visible": "[and(bool(steps('section_database').enableDB),or(equals(steps('section_database').databaseConnectionInfo.databaseType, 'mysql'),equals(steps('section_database').databaseConnectionInfo.databaseType, 'postgresql')))]" + }, + { + "name": "dbPassword", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Database Password", + "confirmPassword": "Confirm password" + }, + "toolTip": "Database Password", + "constraints": { + "required": true, + "regex": "^((?=.*[0-9])(?=.*[a-zA-Z!@#$%^&*])).{5,128}$", + "validationMessage": "The password must be between 5 and 128 characters long and have at least one number." + }, + "options": { + "hideConfirmation": false + }, + "visible": "[and(bool(steps('section_database').enableDB), not(or(steps('section_database').databaseConnectionInfo.enablePswlessConnection, steps('section_database').databaseConnectionInfo.enablePswlessConnection0)))]" + }, + { + "name": "dbIdentity", + "type": "Microsoft.ManagedIdentity.IdentitySelector", + "label": "Connect database with Managed Identity", + "toolTip": { + "userAssignedIdentity": "Select a user assigned identity that has access to your database. For how to create a database user for your managed identity, see https://aka.ms/javaee-db-identity." + }, + "defaultValue": { + "systemAssignedIdentity": "Off" + }, + "options": { + "hideSystemAssignedIdentity": true, + "hideUserAssignedIdentity": false + }, + "visible": "[and(bool(steps('section_database').enableDB), or(steps('section_database').databaseConnectionInfo.enablePswlessConnection, steps('section_database').databaseConnectionInfo.enablePswlessConnection0))]" + } + ], + "visible": "[bool(steps('section_database').enableDB)]" + } + ] + }, + { + "name": "section_tags", + "label": "Tags", + "elements": [ + { + "name": "tagsByResource", + "type": "Microsoft.Common.TagsByResource", + "resources": [ + "${identifier.dnszones}", + "${identifier.networkInterfaces}", + "${identifier.networkSecurityGroups}", + "${identifier.publicIPAddresses}", + "${identifier.privateEndpoints}", + "${identifier.storageAccounts}", + "${identifier.virtualNetworks}", + "${identifier.virtualMachines}", + "${identifier.virtualMachinesExtensions}", + "${identifier.deploymentScripts}", + "${identifier.userAssignedIdentities}", + "${identifier.resourcesDeployment}" + ], + "toolTip": "Tags help you organize your resources and categorize them for billing or management purposes. You can apply tags to resources deployed by the offer." + } + ] + } + ], + "outputs": { + "Location": "[location()]", + "adminPasswordOrKey": "[if(equals(basics('basicsRequired').adminPasswordOrKey.authenticationType, 'password'), basics('basicsRequired').adminPasswordOrKey.password, basics('basicsRequired').adminPasswordOrKey.sshPublicKey)]", + "adminUsername": "[basics('basicsRequired').adminUsername]", + "authenticationType": "[basics('basicsRequired').adminPasswordOrKey.authenticationType]", + "addressPrefixes": "[steps('section_networkingConfiguration').virtualNetwork.addressPrefixes]", + "databaseType": "[steps('section_database').databaseConnectionInfo.databaseType]", + "denyPublicTrafficForAdminServer": "[steps('section_networkingConfiguration').denyPublicTrafficForAdminServer]", + "dbIdentity": "[steps('section_database').databaseConnectionInfo.dbIdentity]", + "dbPassword": "[steps('section_database').databaseConnectionInfo.dbPassword]", + "dbUser": "[steps('section_database').databaseConnectionInfo.dbUser]", + "dbGlobalTranPro": "[steps('section_database').databaseConnectionInfo.dbGlobalTranPro]", + "dnsLabelPrefix": "[steps('section_networkingConfiguration').dnsLabelPrefix]", + "dnszoneName": "[steps('section_networkingConfiguration').customDNSSettings.dnszoneName]", + "dnszoneResourceGroup": "[steps('section_networkingConfiguration').customDNSSettings.dnsZoneResourceGroup]", + "dnszoneAdminConsoleLabel": "[steps('section_networkingConfiguration').customDNSSettings.dnszoneAdminConsoleLabel]", + "dsConnectionURL": "[steps('section_database').databaseConnectionInfo.dsConnectionURL]", + "enableDB": "[bool(steps('section_database').enableDB)]", + "enableCustomDNS": "[bool(steps('section_networkingConfiguration').enableCustomDNS)]", + "enablePswlessConnection": "[or(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection), bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection0))]", + "hasDNSZones": "[bool(if(bool(steps('section_networkingConfiguration').enableCustomDNS), steps('section_networkingConfiguration').customDNSSettings.bringDNSZone, 'false'))]", + "jdbcDataSourceName": "[steps('section_database').databaseConnectionInfo.jdbcDataSourceName]", + "portsToExpose": "[steps('section_networkingConfiguration').portsToExpose]", + "skuUrnVersion": "[basics('skuUrnVersion')]", + "useSystemAssignedManagedIdentity": "[basics('basicsOptional').useSystemAssignedManagedIdentity]", + "vmSize": "[basics('vmSizeSelect')]", + "wlsDomainName": "[basics('basicsOptional').wlsDomainName]", + "wlsPassword": "[basics('basicsRequired').wlsPassword]", + "wlsUserName": "[basics('basicsRequired').wlsUserName]", + "enableHTTPAdminListenPort": "[basics('basicsOptional').enableAdminHTTPListenPort]", + "enableCustomSSL": "[steps('section_sslConfiguration').enableCustomSSL]", + "subnetName": "[steps('section_networkingConfiguration').virtualNetwork.subnets.subnet1.name]", + "subnetPrefix": "[steps('section_networkingConfiguration').virtualNetwork.subnets.subnet1.addressPrefix]", + "tagsByResource": "[steps('section_tags').tagsByResource]", + "uploadedCustomIdentityKeyStoreData": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomIdentityKeyStoreData]", + "uploadedCustomIdentityKeyStorePassphrase": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomIdentityKeyStorePassphrase]", + "uploadedCustomIdentityKeyStoreType": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomIdentityKeyStoreType]", + "uploadedCustomTrustKeyStoreData": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomTrustKeyStoreData]", + "uploadedCustomTrustKeyStorePassPhrase": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomTrustKeyStorePassPhrase]", + "uploadedCustomTrustKeyStoreType": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomTrustKeyStoreType]", + "uploadedPrivateKeyAlias": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedPrivateKeyAlias]", + "uploadedPrivateKeyPassPhrase": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedPrivateKeyPassPhrase]", + "virtualNetworkName": "[steps('section_networkingConfiguration').virtualNetwork.name]", + "virtualNetworkResourceGroupName": "[if(equals(steps('section_networkingConfiguration').virtualNetwork.newOrExisting, 'new'),resourceGroup().name,steps('section_networkingConfiguration').virtualNetwork.resourceGroup)]", + "virtualNetworkNewOrExisting": "[steps('section_networkingConfiguration').virtualNetwork.newOrExisting]" + } + } +} \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/mainTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/mainTemplate.json index 43d71e9f8..0775fbd38 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/mainTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/mainTemplate.json @@ -16,44 +16,12 @@ }, "defaultValue": "" }, - "aadsPortNumber": { - "type": "string", - "defaultValue": "636", - "metadata": { - "description": "Accessible port of the LDAP server." - } - }, - "aadsPublicIP": { - "type": "string", - "defaultValue": "The LDAP server public IP address" - }, - "aadsServerHost": { - "type": "string", - "defaultValue": "ldaps.example.com", - "metadata": { - "description": "The LDAP server host." - } - }, "adminPasswordOrKey": { "type": "securestring", "metadata": { "description": "SSH Key or password for the Virtual Machine. SSH key is recommended." } }, - "adminSSLKeyVaultName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Keyvault name containing Weblogic SSL Certificates" - } - }, - "adminSSLKeyVaultResourceGroup": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Resource Group containing Weblogic SSL Certificates" - } - }, "adminUsername": { "defaultValue": "weblogic", "type": "string", @@ -86,6 +54,20 @@ "description": "One of the supported database types" } }, + "dbGlobalTranPro": { + "defaultValue": "OnePhaseCommit", + "type": "string", + "metadata": { + "description": "Determines the transaction protocol (global transaction processing behavior) for the data source." + } + }, + "dbIdentity": { + "defaultValue": {}, + "type": "object", + "metadata": { + "description": "Managed identity that has access to the data source." + } + }, "dbPassword": { "defaultValue": "", "type": "securestring", @@ -114,15 +96,6 @@ "description": "Unique DNS Name for the Public IP used to access the Virtual Machine." } }, - "dnszoneIdentity": { - "type": "Object", - "defaultValue": { - "type": "UserAssigned", - "userAssignedIdentities": { - "/subscriptions/subscriptionId/resourceGroups/TestResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/TestUserIdentity1": {} - } - } - }, "dnszoneName": { "defaultValue": "contoso.xyz", "type": "string", @@ -151,34 +124,6 @@ "description": "JDBC Connection String" } }, - "elasticsearchEndpoint": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Endpoint of the Elasticsearch instance." - } - }, - "elasticsearchPassword": { - "type": "securestring", - "defaultValue": "[newGuid()]", - "metadata": { - "description": "The credentials to distibute message with REST API to Elasticsearch instance." - } - }, - "elasticsearchUserName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "The credentials to distibute message with REST API to Elasticsearch instance." - } - }, - "enableAAD": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Bool value, if it's set to true, will enable Azure Active Directory after WebLogic Server starts." - } - }, "enableDB": { "defaultValue": false, "type": "bool", @@ -200,22 +145,11 @@ "description": "Boolean value indicating, if custom SSL is enabled or not" } }, - "sslConfigurationAccessOption": { - "type": "string", - "metadata": { - "description": "Options to provide required configuration for SSL configuration" - }, - "allowedValues": [ - "uploadConfig", - "keyVaultStoredConfig" - ], - "defaultValue": "keyVaultStoredConfig" - }, - "enableELK": { + "enablePswlessConnection": { "defaultValue": false, "type": "bool", "metadata": { - "description": "If true, use the supplied parameters to distribute WebLogic Server logs to the Elasticsearch instance." + "description": "True to enable passwordless JDBC connection." } }, "enableHTTPAdminListenPort": { @@ -239,68 +173,20 @@ "description": "JNDI Name for JDBC Datasource" } }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Location for all resources." - } - }, - "keyVaultCustomIdentityKeyStoreDataSecretName": { - "type": "string", - "metadata": { - "description": "Secret name in KeyVault containing Weblogic Custom Identity Keystore Data" - }, - "defaultValue": "CustomIdentityKeyStoreDataSecret" - }, - "keyVaultCustomIdentityKeyStorePassPhraseSecretName": { - "type": "string", - "metadata": { - "description": "Secret name in KeyVault containing Weblogic Custom Identity Keystore Passphrase" - }, - "defaultValue": "CustomIdentityKeyStorePassPhraseSecret" - }, - "keyVaultCustomIdentityKeyStoreType": { - "type": "string", - "metadata": { - "description": "Weblogic Custom Identity Keystore Type" - }, - "defaultValue": "JKS" - }, - "keyVaultCustomTrustKeyStoreDataSecretName": { - "type": "string", - "metadata": { - "description": "Secret name in KeyVault containing Weblogic Custom Trust Store Data" - }, - "defaultValue": "CustomTrustStoreDataSecret" - }, - "keyVaultCustomTrustKeyStorePassPhraseSecretName": { - "type": "string", - "metadata": { - "description": "Secret name in KeyVault containing Weblogic Custom Trust Store Passphrase" - }, - "defaultValue": "CustomTrustStorePassPhraseSecret" - }, - "keyVaultCustomTrustKeyStoreType": { + "guidValue": { "type": "string", - "metadata": { - "description": "Weblogic Custom Trust Store Type" - }, - "defaultValue": "JKS" + "defaultValue": "[newGuid()]" }, - "keyVaultPrivateKeyAliasSecretName": { + "guidTag": { "type": "string", - "metadata": { - "description": "Secret name in KeyVault containing Weblogic Server Private Key Alias" - }, - "defaultValue": "ServerPrivateKeyAlias" + "defaultValue": "[newGuid()]" }, - "keyVaultPrivateKeyPassPhraseSecretName": { + "location": { "type": "string", + "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "Secret name in KeyVault containing Weblogic Server Private KeyPassPhrase" - }, - "defaultValue": "ServerPrivateKeyPassPhraseSecret" + "description": "Location for all resources." + } }, "uploadedCustomIdentityKeyStoreData": { "type": "securestring", @@ -358,28 +244,6 @@ }, "defaultValue": "" }, - "enabledForTemplateDeployment": { - "type": "bool", - "metadata": { - "description": "Property to specify whether Azure Resource Manager is permitted to retrieve secrets from the key vault." - }, - "defaultValue": true - }, - "keyVaultSku": { - "defaultValue": "Standard", - "type": "string", - "metadata": { - "description": "Price tier for Key Vault." - } - }, - "logsToIntegrate": { - "type": "array", - "defaultValue": [ "HTTPAccessLog", "ServerLog", "DomainLog", "DataSourceLog", "StandardErrorAndOutput" ], - "allowedValues": [ "HTTPAccessLog", "ServerLog", "DomainLog", "DataSourceLog", "StandardErrorAndOutput" ], - "metadata": { - "description": "Specify the expeted logs to integrate, you must input at least one log." - } - }, "portsToExpose": { "type": "string", "defaultValue": "80,443,7001-9000", @@ -389,13 +253,21 @@ }, "skuUrnVersion": { "type": "string", - "defaultValue": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "defaultValue": "owls-141200-jdk21-ol94;Oracle:weblogic-141200-jdk21-ol94:owls-141200-jdk21-ol94;latest", "allowedValues": [ - "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest", - "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest", - "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest", - "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest", - "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" + "owls-141200-jdk21-ol94;Oracle:weblogic-141200-jdk21-ol94:owls-141200-jdk21-ol94;latest", + "owls-141200-jdk21-ol810;Oracle:weblogic-141200-jdk21-ol810:owls-141200-jdk21-ol810;latest", + "owls-141200-jdk17-ol94;Oracle:weblogic-141200-jdk17-ol94:owls-141200-jdk17-ol94;latest", + "owls-141200-jdk17-ol810;Oracle:weblogic-141200-jdk17-ol810:owls-141200-jdk17-ol810;latest", + "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", + "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest", + "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest", + "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest", + "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest", + "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest", + "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest", + "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest" ], "metadata": { "description": "The Oracle Linux image with Weblogic and Java preinstalled. Semicolon separated string of Sku, URN, and Version" @@ -415,60 +287,73 @@ "description": "Bool value, if it's set to true, a system assigned managed identity will to be created for the VM(s)" } }, - "vmSizeSelect": { + "vmSize": { "type": "string", "defaultValue": "Standard_A3", "metadata": { "description": "Select appropriate VM Size as per requirement" } }, - "wlsDomainName": { - "defaultValue": "adminDomain", + "virtualNetworkNewOrExisting": { "type": "string", + "defaultValue": "new", + "allowedValues": [ + "new", + "existing" + ], "metadata": { - "description": "Provide Weblogic domain name" + "description": "Specify whether to create a new or existing virtual network for the VM." } }, - "wlsLDAPGroupBaseDN": { + "virtualNetworkName": { "type": "string", - "defaultValue": "null", + "defaultValue": "[concat('wls-vnet', uniqueString(utcNow()))]", "metadata": { - "description": "The base distinguished name (DN) of the tree in the LDAP directory that contains groups." + "description": "Name of the existing or new VNET" } }, - "wlsLDAPPrincipal": { + "virtualNetworkResourceGroupName": { "type": "string", - "defaultValue": "null", + "defaultValue": "[resourceGroup().name]", "metadata": { - "description": "The Distinguished Name (DN) of the LDAP user that WebLogic Server should use to connect to the LDAP server." + "description": "Resource group of Virtual network" } }, - "wlsLDAPPrincipalPassword": { - "type": "securestring", - "defaultValue": "[newGuid()]", + "addressPrefixes": { + "type": "array", + "defaultValue": [ + "10.0.0.0/28" + ], "metadata": { - "description": "The credential (usually a password) used to connect to the LDAP server." + "description": "Address prefix of the VNET." } }, - "wlsLDAPProviderName": { + "subnetName": { "type": "string", - "defaultValue": "AzureActiveDirectoryProvider", + "defaultValue": "wls-subnet", "metadata": { - "description": "The value used for creating authentication provider name of WebLogic Server." + "description": "Name of the existing or new Subnet" } }, - "wlsLDAPSSLCertificate": { + "subnetPrefix": { "type": "string", - "defaultValue": "null", + "defaultValue": "10.0.0.0/29", + "metadata": { + "description": "Address prefix of the subnet" + } + }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, "metadata": { - "description": "Client certificate that will be imported to trust store of SSL." + "description": "${label.tagsLabel}" } }, - "wlsLDAPUserBaseDN": { + "wlsDomainName": { + "defaultValue": "adminDomain", "type": "string", - "defaultValue": "null", "metadata": { - "description": "The base distinguished name (DN) of the tree in the LDAP directory that contains users." + "description": "Provide Weblogic domain name" } }, "wlsPassword": { @@ -486,23 +371,66 @@ } }, "variables": { - "const_currentSubscription": "[subscription().subscriptionId]", - "const_sslConfigurationAccessOptionUploadConfig": "uploadConfig", - "const_sslConfigurationAccessOptionKeyVaultStoredConfig": "keyVaultStoredConfig", - "name_aadLinkedTemplateName": "aadNestedTemplate.json", + "const_globalResourceNameSuffix": "[uniqueString(parameters('guidValue'))]", + "const_guidTag": "[uniqueString(parameters('guidTag'))]", "name_adminCustomSSLLinkedTemplateName": "adminTemplateForCustomSSL.json", "name_adminLinkedTemplateDeployment": "[concat('admin',if(parameters('enableCustomSSL'),'CustomSSL',''),'LinkedTemplate')]", + "name_uamiForPostDeploymentScript" : "uamiForPostDeploymentScript", "name_adminLinkedTemplateName": "adminTemplate.json", + "name_adminVM": "[concat(parameters('adminVMName'), variables('const_globalResourceNameSuffix'))]", "name_dbLinkedTemplate": "dbTemplate.json", "name_dnszonesLinkedTemplateName": "dnszonesTemplate.json", - "name_elkLinkedTemplateName": "elkNestedTemplate.json", + "name_postDeploymentUAMIRolesTemplate" : "postDeploymentUAMIRolesTemplate.json", + "name_postDeploymentTemplate": "postDeploymentTemplate.json", + "name_networkSecurityGroup": "[concat(parameters('dnsLabelPrefix'), '-nsg', variables('const_globalResourceNameSuffix'))]", "name_nsgLinkedTemplateName": "nsgNestedTemplate.json", - "name_keyVaultNestedTemplate": "_keyVaultNestedTemplate.json" + // If adding a new resource, add the resource identifier to the array below + // Also modify createUIDefinition.json to include the new resource + "obj_tagsByResources":{ + "${identifier.dnszones}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.dnszones}')]", + "${identifier.networkInterfaces}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.networkInterfaces}')]", + "${identifier.networkSecurityGroups}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.networkSecurityGroups}')]", + "${identifier.publicIPAddresses}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.publicIPAddresses}')]", + "${identifier.privateEndpoints}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.privateEndpoints}')]", + "${identifier.storageAccounts}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.storageAccounts}')]", + "${identifier.virtualNetworks}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.virtualNetworks}')]", + "${identifier.virtualMachines}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.virtualMachines}')]", + "${identifier.virtualMachinesExtensions}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.virtualMachinesExtensions}')]", + "${identifier.deploymentScripts}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.deploymentScripts}')]", + "${identifier.userAssignedIdentities}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.userAssignedIdentities}')]", + "${identifier.resourcesDeployment}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.resourcesDeployment}')]" + } }, + "functions": [ + { + // This same function is defined in the mainTemplate.json for every other offer. + // Please ensure any changes are applied in all the other places. + "namespace": "funcTags", + "members": { + "tagsFilter": { + "parameters": [ + { + "name": "tagsByResource", + "type": "object" + }, + { + "name": "resourceIdentifier", + "type": "string" + } + ], + "output": { + "type": "object", + "value": "[if(contains(parameters('tagsByResource'), parameters('resourceIdentifier')), parameters('tagsByResource')[parameters('resourceIdentifier')], json('{}'))]" + } + } + } + } + ], "resources": [ { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", "name": "${admin.start}", "properties": { "mode": "Incremental", @@ -517,7 +445,8 @@ { "name": "adminLinkedTemplate", "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", + "apiVersion": "${azure.apiVersionForDeployment}", "condition": "[not(parameters('enableCustomSSL'))]", "properties": { "mode": "Incremental", @@ -532,6 +461,12 @@ "_artifactsLocationSasToken": { "value": "[parameters('_artifactsLocationSasToken')]" }, + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" + }, + "const_guidTag":{ + "value": "[variables('const_guidTag')]" + }, "adminPasswordOrKey": { "value": "[parameters('adminPasswordOrKey')]" }, @@ -539,11 +474,14 @@ "value": "[parameters('adminUsername')]" }, "adminVMName": { - "value": "[parameters('adminVMName')]" + "value": "[variables('name_adminVM')]" }, "authenticationType": { "value": "[parameters('authenticationType')]" }, + "addressPrefixes": { + "value": "[parameters('addressPrefixes')]" + }, "customDNSName": { "value": "[if(parameters('enableCustomDNS'), format('{0}.{1}', parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')),'')]" }, @@ -559,20 +497,41 @@ "location": { "value": "[parameters('location')]" }, + "nsgName": { + "value": "[variables('name_networkSecurityGroup')]" + }, "portsToExpose": { "value": "[parameters('portsToExpose')]" }, "skuUrnVersion": { "value": "[parameters('skuUrnVersion')]" }, + "subnetName": { + "value": "[parameters('subnetName')]" + }, + "subnetPrefix": { + "value": "[parameters('subnetPrefix')]" + }, + "tagsByResource": { + "value": "[variables('obj_tagsByResources')]" + }, "usePreviewImage": { "value": "[parameters('usePreviewImage')]" }, "useSystemAssignedManagedIdentity": { "value": "[parameters('useSystemAssignedManagedIdentity')]" }, - "vmSizeSelect": { - "value": "[parameters('vmSizeSelect')]" + "vmSize": { + "value": "[parameters('vmSize')]" + }, + "virtualNetworkNewOrExisting": { + "value": "[parameters('virtualNetworkNewOrExisting')]" + }, + "virtualNetworkName": { + "value": "[parameters('virtualNetworkName')]" + }, + "virtualNetworkResourceGroupName": { + "value": "[parameters('virtualNetworkResourceGroupName')]" }, "wlsDomainName": { "value": "[parameters('wlsDomainName')]" @@ -585,53 +544,12 @@ } } } - }, - { - "name": "keyVaultNestedTemplate", - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "condition": "[and(parameters('enableCustomSSL'), equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionUploadConfig')))]", - "properties": { - "mode": "Incremental", - "templateLink": { - "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_keyVaultNestedTemplate')))]", - "contentVersion": "1.0.0.0" - }, - "parameters": { - "uploadedCustomIdentityKeyStoreData": { - "value": "[parameters('uploadedCustomIdentityKeyStoreData')]" - }, - "uploadedCustomIdentityKeyStorePassphrase": { - "value": "[parameters('uploadedCustomIdentityKeyStorePassphrase')]" - }, - "uploadedCustomTrustKeyStoreData": { - "value": "[parameters('uploadedCustomTrustKeyStoreData')]" - }, - "uploadedCustomTrustKeyStorePassPhrase": { - "value": "[parameters('uploadedCustomTrustKeyStorePassPhrase')]" - }, - "uploadedPrivateKeyAlias": { - "value": "[parameters('uploadedPrivateKeyAlias')]" - }, - "uploadedPrivateKeyPassPhrase": { - "value": "[parameters('uploadedPrivateKeyPassPhrase')]" - }, - "enabledForTemplateDeployment": { - "value": "[parameters('enabledForTemplateDeployment')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "sku": { - "value": "[parameters('keyVaultSku')]" - } - } - } - }, + }, { "name": "adminCustomSSLLinkedTemplate", "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", "condition": "[parameters('enableCustomSSL')]", "properties": { "mode": "Incremental", @@ -646,6 +564,12 @@ "_artifactsLocationSasToken": { "value": "[parameters('_artifactsLocationSasToken')]" }, + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" + }, + "const_guidTag":{ + "value": "[variables('const_guidTag')]" + }, "adminPasswordOrKey": { "value": "[parameters('adminPasswordOrKey')]" }, @@ -653,11 +577,14 @@ "value": "[parameters('adminUsername')]" }, "adminVMName": { - "value": "[parameters('adminVMName')]" + "value": "[variables('name_adminVM')]" }, "authenticationType": { "value": "[parameters('authenticationType')]" }, + "addressPrefixes": { + "value": "[parameters('addressPrefixes')]" + }, "customDNSName": { "value": "[if(parameters('enableCustomDNS'), format('{0}.{1}', parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')),'')]" }, @@ -673,62 +600,35 @@ "enableHTTPAdminListenPort": { "value": "[parameters('enableHTTPAdminListenPort')]" }, + "nsgName": { + "value": "[variables('name_networkSecurityGroup')]" + }, "location": { "value": "[parameters('location')]" }, - "keyVaultCustomIdentityKeyStoreData": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomIdentityKeyStoreDataSecretName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.customIdentityKeyStoreDataSecretName.value)]" - } + "sslCustomIdentityKeyStoreData": { + "value": "[parameters('uploadedCustomIdentityKeyStoreData')]" }, - "keyVaultCustomIdentityKeyStorePassPhrase": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomIdentityKeyStorePassPhraseSecretName'), reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.customIdentityKeyStorePassPhraseSecretName.value)]" - } + "sslCustomIdentityKeyStorePassPhrase": { + "value": "[parameters('uploadedCustomIdentityKeyStorePassphrase')]" }, - "keyVaultCustomIdentityKeyStoreType": { - "value": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomIdentityKeyStoreType'), parameters('uploadedCustomIdentityKeyStoreType'))]" + "sslCustomIdentityKeyStoreType": { + "value": "[parameters('uploadedCustomIdentityKeyStoreType')]" }, - "keyVaultCustomTrustKeyStoreData": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStoreDataSecretName'), reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.customTrustKeyStoretDataSecretName.value)]" - } + "sslCustomTrustKeyStoreData": { + "value": "[parameters('uploadedCustomTrustKeyStoreData')]" }, - "keyVaultCustomTrustKeyStorePassPhrase": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStorePassPhraseSecretName'), reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.customTrustKeyStorePassPhraseSecretName.value)]" - } + "sslCustomTrustKeyStorePassPhrase": { + "value": "[parameters('uploadedCustomTrustKeyStorePassPhrase')]" }, - "keyVaultCustomTrustKeyStoreType": { - "value": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStoreType'), parameters('uploadedCustomTrustKeyStoreType'))]" + "sslCustomTrustKeyStoreType": { + "value": "[parameters('uploadedCustomTrustKeyStoreType')]" }, - "keyVaultPrivateKeyAlias": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultPrivateKeyAliasSecretName'), reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.privateKeyAliasSecretName.value)]" - } + "sslPrivateKeyAlias": { + "value": "[parameters('uploadedPrivateKeyAlias')]" }, - "keyVaultPrivateKeyPassPhrase": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultPrivateKeyPassPhraseSecretName'), reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.privateKeyPassPhraseSecretName.value)]" - } + "sslPrivateKeyPassPhrase": { + "value": "[parameters('uploadedPrivateKeyPassPhrase')]" }, "portsToExpose": { "value": "[parameters('portsToExpose')]" @@ -736,14 +636,32 @@ "skuUrnVersion": { "value": "[parameters('skuUrnVersion')]" }, + "subnetName": { + "value": "[parameters('subnetName')]" + }, + "subnetPrefix": { + "value": "[parameters('subnetPrefix')]" + }, + "tagsByResource": { + "value": "[variables('obj_tagsByResources')]" + }, "usePreviewImage": { "value": "[parameters('usePreviewImage')]" }, "useSystemAssignedManagedIdentity": { "value": "[parameters('useSystemAssignedManagedIdentity')]" }, - "vmSizeSelect": { - "value": "[parameters('vmSizeSelect')]" + "vmSize": { + "value": "[parameters('vmSize')]" + }, + "virtualNetworkNewOrExisting": { + "value": "[parameters('virtualNetworkNewOrExisting')]" + }, + "virtualNetworkName": { + "value": "[parameters('virtualNetworkName')]" + }, + "virtualNetworkResourceGroupName": { + "value": "[parameters('virtualNetworkResourceGroupName')]" }, "wlsDomainName": { "value": "[parameters('wlsDomainName')]" @@ -755,14 +673,13 @@ "value": "[parameters('wlsUserName')]" } } - }, - "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'keyVaultNestedTemplate')]" - ] + } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", "name": "networkSecurityLinkedTemplate", "properties": { "mode": "Incremental", @@ -775,7 +692,7 @@ "value": "[parameters('denyPublicTrafficForAdminServer')]" }, "networkSecurityGroupName": { - "value": "[concat(parameters('dnsLabelPrefix'), '-nsg')]" + "value": "[variables('name_networkSecurityGroup')]" } } }, @@ -786,9 +703,10 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "dnszonesLinkedTemplate", - "condition": "[parameters('enableCustomDNS')]", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", + "condition": "[and(parameters('enableCustomDNS'), equals(parameters('virtualNetworkNewOrExisting'), 'new'))]", "dependsOn": [ "[resourceId('Microsoft.Resources/deployments', 'networkSecurityLinkedTemplate')]" ], @@ -805,6 +723,9 @@ "_artifactsLocationSasToken": { "value": "[parameters('_artifactsLocationSasToken')]" }, + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" + }, "dnszonesARecordSetNames": { "value": [ "[parameters('dnszoneAdminConsoleLabel')]" @@ -816,9 +737,6 @@ "hasDNSZones": { "value": "[parameters('hasDNSZones')]" }, - "identity": { - "value": "[parameters('dnszoneIdentity')]" - }, "location": { "value": "[parameters('location')]" }, @@ -827,8 +745,11 @@ }, "targetResources": { "value": [ - "[reference(variables('name_adminLinkedTemplateDeployment'), '${azure.apiVersion}').outputs._adminPublicIPId.value]" + "[reference(variables('name_adminLinkedTemplateDeployment'), '${azure.apiVersionForDeployment}').outputs._adminPublicIPId.value]" ] + }, + "tagsByResource": { + "value": "[variables('obj_tagsByResources')]" } } } @@ -839,7 +760,8 @@ "[resourceId('Microsoft.Resources/deployments', 'dnszonesLinkedTemplate')]" ], "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", + "apiVersion": "${azure.apiVersionForDeployment}", "condition": "[parameters('enableDB')]", "properties": { "mode": "Incremental", @@ -855,11 +777,17 @@ "value": "[parameters('_artifactsLocationSasToken')]" }, "adminVMName": { - "value": "[parameters('adminVMName')]" + "value": "[variables('name_adminVM')]" }, "databaseType": { "value": "[parameters('databaseType')]" }, + "dbGlobalTranPro": { + "value": "[parameters('dbGlobalTranPro')]" + }, + "dbIdentity": { + "value": "[parameters('dbIdentity')]" + }, "dbPassword": { "value": "[parameters('dbPassword')]" }, @@ -869,231 +797,118 @@ "dsConnectionURL": { "value": "[parameters('dsConnectionURL')]" }, + "enablePswlessConnection": { + "value": "[parameters('enablePswlessConnection')]" + }, "jdbcDataSourceName": { "value": "[parameters('jdbcDataSourceName')]" }, "location": { "value": "[parameters('location')]" }, - "wlsPassword": { - "value": "[parameters('wlsPassword')]" - }, - "wlsUserName": { - "value": "[parameters('wlsUserName')]" - } - - } - } - }, - { - "name": "aadLinkedTemplate", - "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'dbLinkedTemplate')]" - ], - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "condition": "[and(parameters('enableAAD'),not(parameters('enableCustomSSL')))]", - "properties": { - "mode": "Incremental", - "templateLink": { - "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_aadLinkedTemplateName')))]", - "contentVersion": "1.0.0.0" - }, - "parameters": { - "_artifactsLocation": { - "value": "[parameters('_artifactsLocation')]" - }, - "_artifactsLocationSasToken": { - "value": "[parameters('_artifactsLocationSasToken')]" - }, - "aadsPortNumber": { - "value": "[parameters('aadsPortNumber')]" - }, - "aadsPublicIP": { - "value": "[parameters('aadsPublicIP')]" - }, - "aadsServerHost": { - "value": "[parameters('aadsServerHost')]" - }, - "adminVMName": { - "value": "[parameters('adminVMName')]" - }, - "location": { - "value": "[parameters('location')]" + "tagsByResource": { + "value": "[variables('obj_tagsByResources')]" }, "wlsDomainName": { "value": "[parameters('wlsDomainName')]" }, - "wlsLDAPGroupBaseDN": { - "value": "[parameters('wlsLDAPGroupBaseDN')]" - }, - "wlsLDAPPrincipal": { - "value": "[parameters('wlsLDAPPrincipal')]" - }, - "wlsLDAPPrincipalPassword": { - "value": "[parameters('wlsLDAPPrincipalPassword')]" - }, - "wlsLDAPProviderName": { - "value": "[parameters('wlsLDAPProviderName')]" - }, - "wlsLDAPSSLCertificate": { - "value": "[parameters('wlsLDAPSSLCertificate')]" - }, - "wlsLDAPUserBaseDN": { - "value": "[parameters('wlsLDAPUserBaseDN')]" - }, "wlsPassword": { "value": "[parameters('wlsPassword')]" }, "wlsUserName": { "value": "[parameters('wlsUserName')]" } + } } }, { - "name": "aadLinkedTemplateWithCustomSSL", + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "[variables('name_uamiForPostDeploymentScript')]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'existing')]", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'dbLinkedTemplate')]", - "[resourceId('Microsoft.Resources/deployments', 'keyVaultNestedTemplate')]" + "[resourceId('Microsoft.Resources/deployments', variables('name_adminLinkedTemplateDeployment'))]", + "[resourceId('Microsoft.Resources/deployments', 'networkSecurityLinkedTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'dnszonesLinkedTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'dbLinkedTemplate')]" ], - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "condition": "[and(parameters('enableAAD'),parameters('enableCustomSSL'))]", "properties": { "mode": "Incremental", "templateLink": { - "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_aadLinkedTemplateName')))]", - "contentVersion": "1.0.0.0" - }, + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_postDeploymentUAMIRolesTemplate')))]", + "contentVersion": "1.0.0.0" + }, "parameters": { - "_artifactsLocation": { - "value": "[parameters('_artifactsLocation')]" - }, - "_artifactsLocationSasToken": { - "value": "[parameters('_artifactsLocationSasToken')]" - }, - "aadsPortNumber": { - "value": "[parameters('aadsPortNumber')]" - }, - "aadsPublicIP": { - "value": "[parameters('aadsPublicIP')]" - }, - "aadsServerHost": { - "value": "[parameters('aadsServerHost')]" - }, - "adminVMName": { - "value": "[parameters('adminVMName')]" - }, "location": { "value": "[parameters('location')]" + }, + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" }, - "wlsDomainName": { - "value": "[parameters('wlsDomainName')]" - }, - "wlsLDAPGroupBaseDN": { - "value": "[parameters('wlsLDAPGroupBaseDN')]" - }, - "wlsLDAPPrincipal": { - "value": "[parameters('wlsLDAPPrincipal')]" - }, - "wlsLDAPPrincipalPassword": { - "value": "[parameters('wlsLDAPPrincipalPassword')]" - }, - "wlsLDAPProviderName": { - "value": "[parameters('wlsLDAPProviderName')]" - }, - "wlsLDAPSSLCertificate": { - "value": "[parameters('wlsLDAPSSLCertificate')]" - }, - "wlsLDAPUserBaseDN": { - "value": "[parameters('wlsLDAPUserBaseDN')]" - }, - "wlsPassword": { - "value": "[parameters('wlsPassword')]" - }, - "wlsUserName": { - "value": "[parameters('wlsUserName')]" - }, - "enableCustomSSL": { - "value": "[parameters('enableCustomSSL')]" - }, - "keyVaultCustomTrustKeyStorePassPhrase": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStorePassPhraseSecretName'), reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.customTrustKeyStorePassPhraseSecretName.value)]" - } - }, - "keyVaultCustomTrustKeyStoreType": { - "value": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStoreType'), parameters('uploadedCustomTrustKeyStoreType'))]" + "tagsByResource": { + "value": "[variables('obj_tagsByResources')]" } } } - }, + }, { - "name": "elkLinkedTemplate", + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "postDeplyment", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'existing')]", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'aadLinkedTemplate')]" + "[resourceId('Microsoft.Resources/deployments', variables('name_adminLinkedTemplateDeployment'))]", + "[resourceId('Microsoft.Resources/deployments', 'networkSecurityLinkedTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'dnszonesLinkedTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'dbLinkedTemplate')]", + "[resourceId('Microsoft.Resources/deployments', variables('name_uamiForPostDeploymentScript'))]" ], - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "condition": "[parameters('enableELK')]", "properties": { "mode": "Incremental", "templateLink": { - "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_elkLinkedTemplateName')))]", + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_postDeploymentTemplate')))]", "contentVersion": "1.0.0.0" }, "parameters": { - "_artifactsLocation": { - "value": "[parameters('_artifactsLocation')]" - }, - "_artifactsLocationSasToken": { - "value": "[parameters('_artifactsLocationSasToken')]" - }, - "adminVMName": { - "value": "[parameters('adminVMName')]" - }, - "elasticsearchEndpoint": { - "value": "[parameters('elasticsearchEndpoint')]" - }, - "elasticsearchPassword": { - "value": "[parameters('elasticsearchPassword')]" - }, - "elasticsearchUserName": { - "value": "[parameters('elasticsearchUserName')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "logsToIntegrate": { - "value": "[parameters('logsToIntegrate')]" - }, - "wlsDomainName": { - "value": "[parameters('wlsDomainName')]" - }, - "wlsPassword": { - "value": "[parameters('wlsPassword')]" - }, - "wlsUserName": { - "value": "[parameters('wlsUserName')]" - } + "location": { + "value": "[parameters('location')]" + }, + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" + }, + "tagsByResource": { + "value": "[variables('obj_tagsByResources')]" + }, + "const_guidTag":{ + "value": "[variables('const_guidTag')]" + }, + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + }, + "userAssignedIdentityResourceId":{ + "value": "[reference(variables('name_uamiForPostDeploymentScript'),'${azure.apiVersionForDeployment}').outputs.uamidForPostDeployment.value]" } - } + } + } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", "name": "${admin.end}", "dependsOn": [ "[resourceId('Microsoft.Resources/deployments', variables('name_adminLinkedTemplateDeployment'))]", "[resourceId('Microsoft.Resources/deployments', 'networkSecurityLinkedTemplate')]", "[resourceId('Microsoft.Resources/deployments', 'dnszonesLinkedTemplate')]", "[resourceId('Microsoft.Resources/deployments', 'dbLinkedTemplate')]", - "[resourceId('Microsoft.Resources/deployments', 'aadLinkedTemplate')]", - "[resourceId('Microsoft.Resources/deployments', 'elkLinkedTemplate')]" + "[resourceId('Microsoft.Resources/deployments', variables('name_uamiForPostDeploymentScript'))]", + "[resourceId('Microsoft.Resources/deployments', 'postDeplyment')]" ], "properties": { "mode": "Incremental", @@ -1107,34 +922,42 @@ } ], "outputs": { + "adminVMName": { + "type": "string", + "value": "[variables('name_adminVM')]" + }, "hostname": { "type": "string", - "value": "[reference(variables('name_adminLinkedTemplateDeployment'),'${azure.apiVersion}').outputs.hostname.value]" + "value": "[reference(variables('name_adminLinkedTemplateDeployment'),'${azure.apiVersionForDeployment}').outputs.hostname.value]" }, "sshCommand": { "type": "string", - "value": "[concat('ssh ', parameters('adminUsername'), '@', reference(variables('name_adminLinkedTemplateDeployment'),'${azure.apiVersion}').outputs.hostname.value)]" + "value": "[concat('ssh ', parameters('adminUsername'), '@', reference(variables('name_adminLinkedTemplateDeployment'),'${azure.apiVersionForDeployment}').outputs.hostname.value)]" }, "wlsDomainLocation": { "type": "string", - "value": "[reference(variables('name_adminLinkedTemplateDeployment'),'${azure.apiVersion}').outputs.wlsDomainLocation.value]" + "value": "[reference(variables('name_adminLinkedTemplateDeployment'),'${azure.apiVersionForDeployment}').outputs.wlsDomainLocation.value]" }, "adminConsoleURL": { "type": "string", - "value": "[if(parameters('enableCustomDNS'),format('http://{0}.{1}:7001/console',parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')),reference(variables('name_adminLinkedTemplateDeployment'),'${azure.apiVersion}').outputs.adminConsoleURL.value)]" + "value": "[if(parameters('enableCustomDNS'), uri(format('http://{0}.{1}:7001/console/',parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')), ''),reference(variables('name_adminLinkedTemplateDeployment'),'${azure.apiVersionForDeployment}').outputs.adminConsoleURL.value)]" }, "adminConsoleSecureURL": { "type": "string", - "value": "[if(parameters('enableCustomDNS'),format('https://{0}.{1}:7002/console',parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')),reference(variables('name_adminLinkedTemplateDeployment'),'${azure.apiVersion}').outputs.adminConsoleSecureURL.value)]" + "value": "[if(parameters('enableCustomDNS'), uri(format('https://{0}.{1}:7002/console/',parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')), ''),reference(variables('name_adminLinkedTemplateDeployment'),'${azure.apiVersionForDeployment}').outputs.adminConsoleSecureURL.value)]" }, - "logIndex": { + "adminRemoteConsoleURL": { "type": "string", - "value": "[if(parameters('enableELK'), reference('elkLinkedTemplate', '${azure.apiVersion}').outputs.logIndex.value, '')]" + "value": "[if(parameters('enableCustomDNS'), uri(format('http://{0}.{1}:7001',parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')), ''),reference(variables('name_adminLinkedTemplateDeployment'),'${azure.apiVersionForDeployment}').outputs.adminRemoteConsoleURL.value)]" }, + "adminRemoteConsoleSecureURL": { + "type": "string", + "value": "[if(parameters('enableCustomDNS'), uri(format('https://{0}.{1}:7002',parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')), ''),reference(variables('name_adminLinkedTemplateDeployment'),'${azure.apiVersionForDeployment}').outputs.adminRemoteConsoleSecureURL.value)]" + }, "dnsZoneNameServers": { "type": "array", "condition": "[and(parameters('enableCustomDNS'), not(parameters('hasDNSZones')))]", - "value": "[reference('dnszonesLinkedTemplate','${azure.apiVersion}').outputs.dnsZoneNameServers.value]" + "value": "[reference('dnszonesLinkedTemplate','${azure.apiVersionForDeployment}').outputs.dnsZoneNameServers.value]" } } } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_appendUserManagedIdentity.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_appendUserManagedIdentity.json new file mode 100644 index 000000000..ba47748a4 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_appendUserManagedIdentity.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "vmName": { + "type": "string" + }, + "existingIdentities": { + "type": "object" + }, + "newIdentities": { + "type": "object" + }, + "location": { + "type": "string" + } + }, + "resources": [ + { + "apiVersion": "${azure.apiVersionForVirtualMachines}", + "type": "Microsoft.Compute/virtualMachines", + "name": "[parameters('vmName')]", + "location": "[parameters('location')]", + "identity": { + "type": "userAssigned", + "userAssignedIdentities": "[union(parameters('existingIdentities'),parameters('newIdentities'))]" + } + } + ] +} \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_dbTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_dbTemplate.json new file mode 100644 index 000000000..f88e4117d --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_dbTemplate.json @@ -0,0 +1,254 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." + } + }, + "_artifactsLocationDbTemplate": { + "defaultValue": "[if(contains(parameters('_artifactsLocation'), 'githubusercontent'), parameters('_artifactsLocation'), deployment().properties.templateLink.uri)]", + "type": "string", + "metadata": { + "description": "If we are deploying from the command line, use the passed in _artifactsLocation, otherwise use the default." + } + }, + "_artifactsLocationSasToken": { + "defaultValue": "", + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." + } + }, + "adminVMName": { + "type": "string", + "defaultValue": "adminVM", + "metadata": { + "description": "Admin Server hosting VM name." + } + }, + "databaseType": { + "type": "string", + "metadata": { + "description": "One of the supported database types" + } + }, + "dbGlobalTranPro": { + "defaultValue": "OnePhaseCommit", + "type": "string", + "metadata": { + "description": "Determines the transaction protocol (global transaction processing behavior) for the data source." + } + }, + "dbPassword": { + "defaultValue": "[newGuid()]", + "type": "securestring", + "metadata": { + "description": "Password for Database" + } + }, + "dbUser": { + "type": "string", + "metadata": { + "description": "Userid of Database" + } + }, + "dsConnectionURL": { + "type": "string", + "metadata": { + "description": "JDBC Connection String" + } + }, + "enablePswlessConnection": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "True to enable passwordless connection." + } + }, + "jdbcDataSourceName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "JNDI Name for JDBC Datasource" + } + }, + "location": { + "type": "string", + "metadata": { + "description": "Location for all resources." + } + }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, + "wlsPassword": { + "type": "securestring", + "metadata": { + "description": "Password for your Weblogic domain name" + } + }, + "wlsUserName": { + "type": "string", + "metadata": { + "description": "Username for your Weblogic domain name" + } + } + }, + "variables": { + "const_wlsAdminPort": "7005", + "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", + "name_scriptFilePrefix": "datasourceConfig-", + "name_scriptFileSuffix-sqlserver": "sqlserver.sh", + "name_scriptFileSuffix-oracle": "oracle.sh", + "name_scriptFileSuffix-postgresql": "postgresql.sh", + "name_scriptFileSuffix-mysql": "mysql.sh" + }, + "resources": [ + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${admin.database.start}", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "apiVersion": "${azure.apiVersionForVirtualMachines}", + "type": "Microsoft.Compute/virtualMachines/extensions", + "name": "[concat(parameters('adminVMName'),'/newuserscript')]", + "location": "[parameters('location')]", + "tags": "[parameters('tagsByResource')['${identifier.virtualMachinesExtensions}']]", + "properties": { + "publisher": "Microsoft.Azure.Extensions", + "type": "CustomScript", + "typeHandlerVersion": "2.0", + "autoUpgradeMinorVersion": true, + "settings": { + "fileUris": [ + "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-sqlserver'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-oracle'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-postgresql'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-mysql'), parameters('_artifactsLocationSasToken')))]" + ] + }, + "protectedSettings": { + "commandToExecute": "[concat('sh',' ',variables('name_scriptFilePrefix'),parameters('databaseType'),'.sh <<< \"',variables('const_wlsHome'),' ',parameters('adminVMName'),' ',variables('const_wlsAdminPort'),' ',parameters('wlsUserName'),' ',base64(parameters('wlsPassword')),' ',base64(parameters('jdbcDataSourceName')),' ',base64(parameters('dsConnectionURL')),' ',parameters('dbUser'),' ',base64(parameters('dbPassword')), ' ', parameters('dbGlobalTranPro'), ' ', parameters('enablePswlessConnection'), '\"')]" + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${admin.database.end}", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${database.oracle}", + "condition": "[if(contains(parameters('databaseType'), 'oracle'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${database.postgresql}", + "condition": "[if(contains(parameters('databaseType'), 'postgresql'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${database.sqlserver}", + "condition": "[if(contains(parameters('databaseType'), 'sqlserver'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${database.mysql}", + "condition": "[if(contains(parameters('databaseType'), 'mysql'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + } + ], + "outputs": { + "artifactsLocationPassedIn": { + "type": "string", + "value": "[parameters('_artifactsLocation')]" + } + } +} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_dnszones/_createDNSZonesTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_dnszones/_createDNSZonesTemplate.json index ee049b798..52164197b 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_dnszones/_createDNSZonesTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_dnszones/_createDNSZonesTemplate.json @@ -38,6 +38,13 @@ "description": "References to Azure resources from where the DNS resource value is taken. Each item is corresponding to values of dnszonesARecordSetNames." } }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, "ttl": { "type": "int", "defaultValue": 3600, @@ -62,6 +69,7 @@ "type": "Microsoft.Network/dnszones", "apiVersion": "${azure.apiVersionForDNSZone}", "name": "[parameters('dnszoneName')]", + "tags": "[parameters('tagsByResource')['${identifier.dnszones}']]", "location": "[parameters('location')]", "properties": { "zoneType": "Public" diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_dnszones/_uamiAndRoleAssignment.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_dnszones/_uamiAndRoleAssignment.json new file mode 100644 index 000000000..766dd3089 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_dnszones/_uamiAndRoleAssignment.json @@ -0,0 +1,108 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "_globalResourceNameSuffix": { + "type": "string" + }, + "location": { + "type": "string" + }, + "uamiName": { + "type": "string" + }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + } + }, + "functions": [], + "variables": { + "const_roleDefinitionIdOfContributor": "b24988ac-6180-42a0-ab88-20f7382dd24c", + "name_deploymentScriptContributorRoleAssignmentName": "[guid(format('{0}{1}Deployment Script', parameters('_globalResourceNameSuffix'), parameters('uamiName')))]" + }, + "resources": [ + { + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "${azure.apiVersionForIdentity}", + "name": "[parameters('uamiName')]", + "location": "[parameters('location')]", + "tags": "[parameters('tagsByResource')['${identifier.userAssignedIdentities}']]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "[variables('name_deploymentScriptContributorRoleAssignmentName')]", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "subscriptionId": "[subscription().subscriptionId]", + "location": "[parameters('location')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "_globalResourceNameSuffix": { + "value": "[parameters('_globalResourceNameSuffix')]" + }, + "roleDefinition": { + "value": "[variables('const_roleDefinitionIdOfContributor')]" + }, + "principalId": { + "value": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('uamiName'))).principalId]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "_globalResourceNameSuffix": { + "type": "string", + "defaultValue": "" + }, + "roleDefinition": { + "type": "string", + "defaultValue": "" + }, + "principalId": { + "type": "string", + "defaultValue": "" + } + }, + "functions": [], + "variables": { + "name_roleAssignmentName": "[guid(format('{0}{1}Role assignment in subscription scope', parameters('_globalResourceNameSuffix'), parameters('principalId')))]" + }, + "resources": [ + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "${azure.apiVersionForRoleAssignment}", + "name": "[variables('name_roleAssignmentName')]", + "properties": { + "description": "Assign subscription scope role to User Assigned Managed Identity ", + "principalId": "[parameters('principalId')]", + "principalType": "ServicePrincipal", + "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinition'))]" + } + } + ], + "outputs": { + "roleId": { + "type": "string", + "value": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinition'))]" + } + } + } + } + } + ], + "outputs": { + "uamiIdForDeploymentScript": { + "type": "string", + "value": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('uamiName'))]" + } + } + } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_dnszones/_updateDNSZonesTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_dnszones/_updateDNSZonesTemplate.json index 74207d21a..4794a5891 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_dnszones/_updateDNSZonesTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_dnszones/_updateDNSZonesTemplate.json @@ -22,6 +22,12 @@ "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." } }, + "_globalResourceNameSuffix": { + "type": "string", + "metadata": { + "description": "The suffix to be added to the globally unique resource name." + } + }, "dnszonesARecordSetNames": { "type": "array", "metadata": { @@ -46,12 +52,6 @@ "description": "Azure DNS Zone name." } }, - "identity": { - "type": "Object", - "metadata": { - "description": "Managed identity to be used for the deployment script. Currently, only user-assigned MSI is supported." - } - }, "location": { "type": "string", "metadata": { @@ -70,6 +70,13 @@ "description": "References to Azure resources from where the DNS resource value is taken. Each item is corresponding to values of dnszonesARecordSetNames." } }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, "ttl": { "type": "int", "defaultValue": 3600, @@ -105,21 +112,108 @@ } ], "variables": { - "name_scriptDNSConfiguration": "updateDNSZones.sh" + "name_deploymentScriptUserDefinedManagedIdentity": "wls-vm-deployment-script-user-defined-managed-itentity", + "name_scriptDNSConfiguration": "updateDNSZones.sh", + "name_templateUAMIDeployment": "_uamiAndRoleAssignment.json" }, "resources": [ + { + "type": "Microsoft.Resources/deployments", + "name": "uamiDeployment", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/_dnszones/', variables('name_templateUAMIDeployment')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "_globalResourceNameSuffix": { + "value": "[parameters('_globalResourceNameSuffix')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "uamiName": { + "value": "[variables('name_deploymentScriptUserDefinedManagedIdentity')]" + }, + "tagsByResource": { + "value": "[parameters('tagsByResource')]" + } + } + } + }, { "type": "Microsoft.Resources/deploymentScripts", "apiVersion": "${azure.apiVersionForDeploymentScript}", - "name": "script-createDNSRecords", + "tags": "[parameters('tagsByResource')['${identifier.deploymentScripts}']]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'uamiDeployment')]" + ], + "name": "[concat('script-createDNSRecords', parameters('_globalResourceNameSuffix'))]", "location": "[parameters('location')]", - "identity": "[parameters('identity')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('name_deploymentScriptUserDefinedManagedIdentity'))]": {} + } + }, "kind": "AzureCLI", "properties": { "forceUpdateTag": "[parameters('utcValue')]", - "AzCliVersion": "2.15.0", + "AzCliVersion": "${azure.cli.version}", "timeout": "PT30M", - "arguments": "[format('{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10}', parameters('resourceGroup'), parameters('dnszoneName'), array.join(parameters('dnszonesARecordSetNames')),array.join(parameters('targetResources')), length(parameters('dnszonesARecordSetNames')), length(parameters('targetResources')), parameters('ttl'), array.join(parameters('dnszonesCNAMERecordSetNames')),array.join(parameters('dnszonesCNAMEAlias')),length(parameters('dnszonesCNAMERecordSetNames')), length(parameters('dnszonesCNAMEAlias')))]", + "environmentVariables": [ + { + "name": "DNS_CNAME_ALIAS", + "value": "[array.join(parameters('dnszonesCNAMEAlias'))]" + }, + { + "name": "DNS_CNAME_ALIAS_LENGTH", + "value": "[length(parameters('dnszonesCNAMEAlias'))]" + }, + { + "name": "DNS_CNAME_RECORDSET_LENGTH", + "value": "[length(parameters('dnszonesCNAMERecordSetNames'))]" + }, + { + "name": "DNS_CNAME_RECORDSET_NAMES", + "value": "[array.join(parameters('dnszonesCNAMERecordSetNames'))]" + }, + { + "name": "DNS_RECORDSET_NAMES", + "value": "[array.join(parameters('dnszonesARecordSetNames'))]" + }, + { + "name": "DNS_RECORD_NAMES_LENGTH", + "value": "[length(parameters('dnszonesARecordSetNames'))]" + }, + { + "name": "DNS_TARGET_RESOURCES_LENGTH", + "value": "[length(parameters('targetResources'))]" + }, + { + "name": "DNS_TARGET_RESOURCES", + "value": "[array.join(parameters('targetResources'))]" + }, + { + "name": "DNS_RECORD_TTL", + "value": "[parameters('ttl')]" + }, + { + "name": "DNS_ZONE_NAME", + "value": "[parameters('dnszoneName')]" + }, + { + "name": "MANAGED_IDENTITY_ID", + "value": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('name_deploymentScriptUserDefinedManagedIdentity'))]" + }, + { + "name": "RESOURCE_GROUP_NAME", + "value": "[parameters('resourceGroup')]" + } + ], "primaryScriptUri": "[uri(parameters('_artifactsLocationDNSZonesTemplate'), concat('../../scripts/', variables('name_scriptDNSConfiguration'), parameters('_artifactsLocationSasToken')))]", "cleanupPreference": "OnSuccess", "retentionInterval": "P1D" diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_installJdbcLibsTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_installJdbcLibsTemplate.json new file mode 100644 index 000000000..381354058 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_installJdbcLibsTemplate.json @@ -0,0 +1,108 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." + } + }, + "_artifactsLocationInstallJdbcLibsTemplate": { + "defaultValue": "[if(contains(parameters('_artifactsLocation'), 'githubusercontent'), parameters('_artifactsLocation'), deployment().properties.templateLink.uri)]", + "type": "string", + "metadata": { + "description": "If we are deploying from the command line, use the passed in _artifactsLocation, otherwise use the default." + } + }, + "_artifactsLocationSasToken": { + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." + }, + "defaultValue": "" + }, + "adminVMName": { + "type": "string", + "defaultValue": "adminVM", + "metadata": { + "description": "Admin Server hosting VM name." + } + }, + "databaseType": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "One of the supported database types" + } + }, + "enablePswlessConnection": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "True to enable passwordless connection." + } + }, + "location": { + "type": "string", + "metadata": { + "description": "Location for all resources." + } + }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, + "wlsDomainName": { + "type": "string", + "defaultValue": "wlsd", + "metadata": { + "description": "Provide Weblogic domain name" + } + }, + "wlsPassword": { + "type": "securestring", + "metadata": { + "description": "Password for your Weblogic domain name" + } + }, + "wlsUserName": { + "type": "string", + "metadata": { + "description": "Username for your Weblogic domain name" + } + } + }, + "variables": { + "const_wlsAdminPort": "7005", + "const_wlsDomainPath": "[concat('/u01/domains/', parameters('wlsDomainName'))]", + "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", + "name_scriptInstallJdbcLibs": "installJdbcDrivers.sh" + }, + "resources": [ + { + "apiVersion": "${azure.apiVersionForVirtualMachines}", + "type": "Microsoft.Compute/virtualMachines/extensions", + "name": "[concat(parameters('adminVMName'), '/newuserscript')]", + "tags": "[parameters('tagsByResource')['${identifier.virtualMachinesExtensions}']]", + "location": "[parameters('location')]", + "properties": { + "publisher": "Microsoft.Azure.Extensions", + "type": "CustomScript", + "typeHandlerVersion": "2.0", + "autoUpgradeMinorVersion": true, + "settings": { + "fileUris": [ + "[uri(parameters('_artifactsLocationInstallJdbcLibsTemplate'), concat('../scripts/', variables('name_scriptInstallJdbcLibs'), parameters('_artifactsLocationSasToken')))]" + ] + }, + "protectedSettings": { + "commandToExecute": "[concat('sh',' ',variables('name_scriptInstallJdbcLibs'),' <<< \"',variables('const_wlsHome'),' ',variables('const_wlsDomainPath'),' ','admin', ' ', parameters('adminVMName'), ' ',variables('const_wlsAdminPort'),' ',parameters('wlsUserName'),' ',base64(parameters('wlsPassword')),' ',parameters('databaseType'),' ',parameters('enablePswlessConnection'), '\"')]" + } + } + } + ] +} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_keyVaultNestedTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_keyVaultNestedTemplate.json deleted file mode 100644 index 56bdb2c85..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_keyVaultNestedTemplate.json +++ /dev/null @@ -1,197 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "uploadedCustomIdentityKeyStoreData": { - "type": "securestring", - "metadata": { - "description": "Custom Identity KeyStore Data" - } - }, - "uploadedCustomIdentityKeyStorePassphrase": { - "type": "securestring", - "metadata": { - "description": "Custom Identity KeyStore Passphrase" - } - }, - "uploadedCustomTrustKeyStoreData": { - "type": "securestring", - "metadata": { - "description": "Custom Trust KeyStore Data" - } - }, - "uploadedCustomTrustKeyStorePassPhrase": { - "type": "securestring", - "metadata": { - "description": "Custom Trust KeyStore PassPhrase" - } - }, - "uploadedPrivateKeyAlias": { - "type": "string", - "metadata": { - "description": "Alias of the private key" - } - }, - "uploadedPrivateKeyPassPhrase": { - "type": "securestring", - "metadata": { - "description": "Password of the private key" - } - }, - "enabledForTemplateDeployment": { - "type": "bool", - "metadata": { - "description": "Property to specify whether Azure Resource Manager is permitted to retrieve secrets from the key vault." - }, - "defaultValue": true - }, - "location": { - "type": "string", - "metadata": { - "description": "The supported Azure location where the key vault should be created." - } - }, - "sku": { - "type": "string", - "metadata": { - "description": "Price tier for Key Vault." - }, - "defaultValue": "Standard" - }, - "utcValue": { - "type": "string", - "defaultValue": "[utcNow()]", - "metadata": { - "description": "Current deployment time. Used as a tag in deployment script." - } - } - }, - "variables": { - "name_keyVaultName": "[take(concat('wls-kv', parameters('utcValue'), uniqueString(resourceGroup().id, deployment().name)), 24)]", - "name_customIdentityKeyStoreDataSecretName": "customIdentityKeyStoreData", - "name_customIdentityKeyStorePassPhraseSecretName": "customIdentityKeyStorePassPhrase", - "name_customTrustKeyStoreDataSecretName": "customTrustKeyStoreData", - "name_customTrustKeyStorePassPhraseSecretName": "customTrustKeyStorePassPhrase", - "name_privateKeyAliasSecretName": "privateKeyAlias", - "name_privateKeyPassPhraseSecretName": "privateKeyPassPhrase" - }, - "resources": [ - { - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[variables('name_keyVaultName')]", - "location": "[parameters('location')]", - "type": "Microsoft.KeyVault/vaults", - "properties": { - "enabledForTemplateDeployment": "[parameters('enabledForTemplateDeployment')]", - "sku": { - "name": "[parameters('sku')]", - "family": "A" - }, - "accessPolicies": [], - "tenantId": "[subscription().tenantId]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(variables('name_keyVaultName'), '/', variables('name_customIdentityKeyStoreDataSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', variables('name_keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedCustomIdentityKeyStoreData')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(variables('name_keyVaultName'), '/', variables('name_customIdentityKeyStorePassPhraseSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', variables('name_keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedCustomIdentityKeyStorePassphrase')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(variables('name_keyVaultName'), '/', variables('name_customTrustKeyStoreDataSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', variables('name_keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedCustomTrustKeyStoreData')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(variables('name_keyVaultName'), '/', variables('name_customTrustKeyStorePassPhraseSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', variables('name_keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedCustomTrustKeyStorePassPhrase')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(variables('name_keyVaultName'), '/', variables('name_privateKeyAliasSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', variables('name_keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedPrivateKeyAlias')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(variables('name_keyVaultName'), '/', variables('name_privateKeyPassPhraseSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', variables('name_keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedPrivateKeyPassPhrase')]" - } - } - ], - "outputs": { - "keyVaultName": { - "type": "string", - "value": "[variables('name_keyVaultName')]" - }, - "customIdentityKeyStoreDataSecretName": { - "type": "string", - "value": "[variables('name_customIdentityKeyStoreDataSecretName')]" - }, - "customIdentityKeyStorePassPhraseSecretName": { - "type": "string", - "value": "[variables('name_customIdentityKeyStorePassPhraseSecretName')]" - }, - "customTrustKeyStoretDataSecretName": { - "type": "string", - "value": "[variables('name_customTrustKeyStoreDataSecretName')]" - }, - "customTrustKeyStorePassPhraseSecretName": { - "type": "string", - "value": "[variables('name_customTrustKeyStorePassPhraseSecretName')]" - }, - "privateKeyAliasSecretName": { - "type": "string", - "value": "[variables('name_privateKeyAliasSecretName')]" - }, - "privateKeyPassPhraseSecretName": { - "type": "string", - "value": "[variables('name_privateKeyPassPhraseSecretName')]" - } - } -} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_pswlessDbTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_pswlessDbTemplate.json new file mode 100644 index 000000000..b73945dfe --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/_pswlessDbTemplate.json @@ -0,0 +1,304 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." + } + }, + "_artifactsLocationSasToken": { + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." + }, + "defaultValue": "" + }, + "adminVMName": { + "type": "string", + "defaultValue": "adminVM", + "metadata": { + "description": "Admin Server hosting VM name." + } + }, + "databaseType": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "One of the supported database types" + } + }, + "dbGlobalTranPro": { + "defaultValue": "OnePhaseCommit", + "type": "string", + "metadata": { + "description": "Determines the transaction protocol (global transaction processing behavior) for the data source." + } + }, + "dbIdentity": { + "defaultValue": {}, + "type": "object", + "metadata": { + "description": "Managed identity that has access to the data source." + } + }, + "dbUser": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Userid of Database" + } + }, + "dsConnectionURL": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "JDBC Connection String" + } + }, + "jdbcDataSourceName": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "JNDI Name for JDBC Datasource" + } + }, + "location": { + "type": "string", + "metadata": { + "description": "Location for all resources." + } + }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, + "wlsDomainName": { + "type": "string", + "defaultValue": "adminDomain", + "metadata": { + "description": "Provide Weblogic domain name" + } + }, + "wlsPassword": { + "type": "securestring", + "metadata": { + "description": "Password for your Weblogic domain name" + } + }, + "wlsUserName": { + "type": "string", + "metadata": { + "description": "Username for your Weblogic domain name" + } + } + }, + "variables": { + "const_connectionString": "[if(and(equals(parameters('databaseType'),'sqlserver'), equals(last(parameters('dsConnectionURL')),';')), take(parameters('dsConnectionURL'), add(length(parameters('dsConnectionURL')),-1)),parameters('dsConnectionURL'))]", + "const_identityAPIVersion": "${azure.apiVersionForIdentity}", + "const_msiDefaultUser": "msiUser", + "name_appendIdentityTemplate": "_appendUserManagedIdentity.json", + "name_installJdbcLibsTemplate": "_installJdbcLibsTemplate.json", + "name_dbTemplate": "_dbTemplate.json", + "array_msiClientId": { + "mysql": "azure.clientId", + "postgresql": "azure.clientId", + "sqlserver": "msiClientId" + }, + "array_azureJdbcPlugins": { + "mysql": "defaultAuthenticationPlugin=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin&authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin", + "postgresql": "authenticationPluginClassName=com.azure.identity.extensions.jdbc.postgresql.AzurePostgresqlAuthenticationPlugin", + "sqlserver": "authentication=ActiveDirectoryMSI" + }, + "array_urlJoiner": { + "mysql": "[if(contains(variables('const_connectionString'), '?'), '&', '?')]", + "postgresql": "[if(contains(variables('const_connectionString'), '?'), '&', '?')]", + "sqlserver": ";" + }, + "array_paramJoiner": { + "mysql": "&", + "postgresql": "&", + "sqlserver": ";" + }, + "obj_dbIdentity": { + "[items(parameters('dbIdentity').userAssignedIdentities)[0].key]": {} + }, + "obj_empty": {} + }, + "resources": [ + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${admin.pswless.database.start}", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "assignDbIdentityToAdminVM", + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_appendIdentityTemplate')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "vmName": { + "value": "[parameters('adminVMName')]" + }, + "newIdentities": { + "value": "[variables('obj_dbIdentity')]" + }, + "existingIdentities": { + "value": "[if(equals(reference(resourceId('Microsoft.Compute/virtualMachines',parameters('adminVMName')), '${azure.apiVersionForVirtualMachines}', 'Full').identity.type,'UserAssigned'),reference(resourceId('Microsoft.Compute/virtualMachines',parameters('adminVMName')), '${azure.apiVersionForVirtualMachines}', 'Full').identity.userAssignedIdentities, variables('obj_empty'))]" + }, + "location": { + "value": "[parameters('location')]" + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "installJdbcLibsTemplate", + "condition": "[or(equals(parameters('databaseType'),'mysql'), equals(parameters('databaseType'),'postgresql'))]", + "dependsOn": [ + "assignDbIdentityToAdminVM" + ], + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_installJdbcLibsTemplate')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + }, + "adminVMName": { + "value": "[parameters('adminVMName')]" + }, + "databaseType": { + "value": "[parameters('databaseType')]" + }, + "enablePswlessConnection": { + "value": true + }, + "location": { + "value": "[parameters('location')]" + }, + "tagsByResource": { + "value": "[parameters('tagsByResource')]" + }, + "wlsDomainName": { + "value": "[parameters('wlsDomainName')]" + }, + "wlsPassword": { + "value": "[parameters('wlsPassword')]" + }, + "wlsUserName": { + "value": "[parameters('wlsUserName')]" + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "passwordlessDatasourceDeployment", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'installJdbcLibsTemplate')]" + ], + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_dbTemplate')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + }, + "adminVMName": { + "value": "[parameters('adminVMName')]" + }, + "databaseType": { + "value": "[parameters('databaseType')]" + }, + "dbGlobalTranPro": { + "value": "[parameters('dbGlobalTranPro')]" + }, + "dsConnectionURL": { + "value": "[uri(format('{0}{4}{1}{5}{2}={3}', variables('const_connectionString'), variables('array_azureJdbcPlugins')[parameters('databaseType')], variables('array_msiClientId')[parameters('databaseType')], reference(items(parameters('dbIdentity').userAssignedIdentities)[0].key,variables('const_identityAPIVersion'), 'full').properties.clientId, variables('array_urlJoiner')[parameters('databaseType')], variables('array_paramJoiner')[parameters('databaseType')]), '')]" + }, + "dbUser": { + "value": "[if(equals(parameters('databaseType'), 'sqlserver'), variables('const_msiDefaultUser'), parameters('dbUser'))]" + }, + "enablePswlessConnection": { + "value": true + }, + "jdbcDataSourceName": { + "value": "[parameters('jdbcDataSourceName')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "tagsByResource": { + "value": "[parameters('tagsByResource')]" + }, + "wlsPassword": { + "value": "[parameters('wlsPassword')]" + }, + "wlsUserName": { + "value": "[parameters('wlsUserName')]" + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${admin.pswless.database.end}", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'passwordlessDatasourceDeployment')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + } + ], + "outputs": { + "artifactsLocationPassedIn": { + "type": "string", + "value": "[parameters('_artifactsLocation')]" + } + } +} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/aadNestedTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/aadNestedTemplate.json deleted file mode 100644 index 55733141d..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/aadNestedTemplate.json +++ /dev/null @@ -1,205 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "_artifactsLocation": { - "type": "string", - "metadata": { - "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." - } - }, - "_artifactsLocationAADTemplate": { - "defaultValue": "[if(contains(parameters('_artifactsLocation'), 'githubusercontent'), parameters('_artifactsLocation'), deployment().properties.templateLink.uri)]", - "type": "string", - "metadata": { - "description": "If we are deploying from the command line, use the passed in _artifactsLocation, otherwise use the default." - } - }, - "_artifactsLocationSasToken": { - "defaultValue":"", - "type": "securestring", - "metadata": { - "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." - } - }, - "aadsPortNumber": { - "type": "string", - "defaultValue": "636", - "metadata": { - "description": "Accessible port of the LDAP server." - } - }, - "aadsPublicIP": { - "type": "string", - "defaultValue": "The LDAP server public IP address" - }, - "aadsServerHost": { - "type": "string", - "defaultValue": "ldaps.example.com", - "metadata": { - "description": "The LDAP server host." - } - }, - "adminVMName": { - "type": "string", - "defaultValue": "adminVM", - "metadata": { - "description": "Admin Server hosting VM name." - } - }, - "location": { - "type": "string", - "metadata": { - "description": "Location for all resources." - } - }, - "wlsDomainName": { - "type": "string", - "metadata": { - "description": "Provide Weblogic domain name" - } - }, - "wlsLDAPGroupBaseDN": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "The base distinguished name (DN) of the tree in the LDAP directory that contains groups." - } - }, - "wlsLDAPPrincipal": { - "type": "securestring", - "defaultValue": "", - "metadata": { - "description": "The Distinguished Name (DN) of the LDAP user that WebLogic Server should use to connect to the LDAP server." - } - }, - "wlsLDAPPrincipalPassword": { - "type": "securestring", - "defaultValue": "[newGuid()]", - "metadata": { - "description": "The credential (usually a password) used to connect to the LDAP server." - } - }, - "wlsLDAPProviderName": { - "type": "string", - "defaultValue": "AzureActiveDirectoryProvider", - "metadata": { - "description": "The value used for creating authentication provider name of WebLogic Server." - } - }, - "wlsLDAPSSLCertificate": { - "type": "securestring", - "defaultValue": "", - "metadata": { - "description": "Client certificate that will be imported to trust store of SSL." - } - }, - "wlsLDAPUserBaseDN": { - "type": "securestring", - "defaultValue": "", - "metadata": { - "description": "The base distinguished name (DN) of the tree in the LDAP directory that contains users." - } - }, - "wlsPassword": { - "type": "securestring", - "metadata": { - "description": "Password for your Weblogic domain name" - } - }, - "wlsUserName": { - "type": "string", - "metadata": { - "description": "Username for your Weblogic domain name" - } - }, - "enableCustomSSL": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Boolean value indicating, if custom SSL is enabled or not" - } - }, - "keyVaultCustomTrustKeyStorePassPhrase": { - "type": "securestring", - "defaultValue": "", - "metadata": { - "description": "Weblogic Custom Trust Store Passphrase" - } - }, - "keyVaultCustomTrustKeyStoreType": { - "type": "string", - "defaultValue": "null", - "metadata": { - "description": "Weblogic Custom Trust Store Type (JKS or PKCS12)" - } - } - }, - "variables": { - "const_aadParameters": "[concat(parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('wlsDomainName'),' ',parameters('wlsLDAPProviderName'), ' ', parameters('aadsServerHost'), ' ', parameters('aadsPortNumber'), ' ', concat('\"',parameters('wlsLDAPPrincipal'),'\"'), ' ', parameters('wlsLDAPPrincipalPassword'), ' ', concat('\"',parameters('wlsLDAPUserBaseDN'),'\"'), ' ', concat('\"',parameters('wlsLDAPGroupBaseDN'),'\"'), ' ', variables('const_wlsHome'),' ',parameters('adminVMName'),' ',variables('const_wlsAdminPort'),' ',parameters('wlsLDAPSSLCertificate'), ' ', parameters('aadsPublicIP'), ' ', variables('const_adminServerName'), ' ', variables('const_wlsDomainPath'),' ',parameters('enableCustomSSL'),' ',base64(parameters('keyVaultCustomTrustKeyStorePassPhrase')),' ',base64(parameters('keyVaultCustomTrustKeyStoreType')))]", - "const_adminServerName": "admin", - "const_wlsAdminPort": "7005", - "const_wlsDomainPath": "[concat('/u01/domains/', parameters('wlsDomainName'))]", - "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", - "name_scriptAADConfiguration": "aadIntegration.sh" - }, - "resources": [ - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${admin.aad.start}", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(parameters('adminVMName'),'/newuserscript')]", - "location": "[parameters('location')]", - "properties": { - "publisher": "Microsoft.Azure.Extensions", - "type": "CustomScript", - "typeHandlerVersion": "2.0", - "autoUpgradeMinorVersion": true, - "settings": { - "fileUris": [ - "[uri(parameters('_artifactsLocationAADTemplate'), concat('../scripts/', variables('name_scriptAADConfiguration'), parameters('_artifactsLocationSasToken')))]" - ] - }, - "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptAADConfiguration'),' <<< \"', variables('const_aadParameters'),'\"')]" - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${admin.aad.end}", - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" - ], - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - } - ], - "outputs": { - "artifactsLocationPassedIn": { - "type": "string", - "value": "[parameters('_artifactsLocation')]" - } - } -} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/adminTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/adminTemplate.json index aec448257..f415721a6 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/adminTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/adminTemplate.json @@ -21,6 +21,18 @@ "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." } }, + "_globalResourceNameSuffix": { + "type": "string", + "metadata": { + "description": "A unique suffix that was specified during the deployment of the solution template." + } + }, + "const_guidTag" :{ + "type": "string", + "metadata": { + "description": "A unique tag for resources." + } + }, "adminPasswordOrKey": { "type": "securestring", "metadata": { @@ -88,6 +100,12 @@ "description": "Location for all resources." } }, + "nsgName": { + "type": "string", + "metadata": { + "description": "Network Security Group name" + } + }, "portsToExpose": { "type": "string", "defaultValue": "80,443,7001-9000", @@ -97,13 +115,21 @@ }, "skuUrnVersion": { "type": "string", - "defaultValue": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "defaultValue": "owls-141200-jdk21-ol94;Oracle:weblogic-141200-jdk21-ol94:owls-141200-jdk21-ol94;latest", "allowedValues": [ - "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest", - "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest", - "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest", - "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest", - "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" + "owls-141200-jdk21-ol94;Oracle:weblogic-141200-jdk21-ol94:owls-141200-jdk21-ol94;latest", + "owls-141200-jdk21-ol810;Oracle:weblogic-141200-jdk21-ol810:owls-141200-jdk21-ol810;latest", + "owls-141200-jdk17-ol94;Oracle:weblogic-141200-jdk17-ol94:owls-141200-jdk17-ol94;latest", + "owls-141200-jdk17-ol810;Oracle:weblogic-141200-jdk17-ol810:owls-141200-jdk17-ol810;latest", + "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", + "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest", + "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest", + "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest", + "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest", + "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest", + "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest", + "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest" ], "metadata": { "description": "The Oracle Linux image with Weblogic and Java preinstalled. Semicolon separated string of Sku, URN, and Version" @@ -123,13 +149,61 @@ "description": "Bool value, if it's set to true, a system assigned managed identity will to be created for the VM(s)" } }, - "vmSizeSelect": { + "vmSize": { "type": "string", "defaultValue": "Standard_A3", "metadata": { "description": "Select appropriate VM Size as per requirement" } }, + "virtualNetworkNewOrExisting": { + "type": "string", + "defaultValue": "new", + "allowedValues": [ + "new", + "existing" + ], + "metadata": { + "description": "Specify whether to create a new or existing virtual network for the VM." + } + }, + "virtualNetworkName": { + "type": "string", + "defaultValue": "wls-vnet", + "metadata": { + "description": "Name of the existing or new VNET" + } + }, + "virtualNetworkResourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "Resource group of Virtual network" + } + }, + "addressPrefixes": { + "type": "array", + "defaultValue": [ + "10.0.0.0/28" + ], + "metadata": { + "description": "Address prefix of the VNET." + } + }, + "subnetName": { + "type": "string", + "defaultValue": "wls-subnet", + "metadata": { + "description": "Name of the existing or new Subnet" + } + }, + "subnetPrefix": { + "type": "string", + "defaultValue": "10.0.0.0/29", + "metadata": { + "description": "Address prefix of the subnet" + } + }, "wlsDomainName": { "type": "string", "metadata": { @@ -147,10 +221,17 @@ "metadata": { "description": "Username for your Weblogic domain name" } + }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } } }, "variables": { - "const_addressPrefix": "10.0.0.0/16", + "const_addressPrefix": "[parameters('addressPrefixes')]", "const_hyphen": "-", "const_imageOffer": "[concat('weblogic',variables('const_hyphen'), split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[1],variables('const_hyphen'),split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[2],variables('const_hyphen'),split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[3],if(parameters('usePreviewImage'),'-preview',''))]", "const_imagePublisher": "oracle", @@ -168,30 +249,37 @@ "const_publicIPAddressType": "Dynamic", "const_requiredPortrange": ",65200-65535,5556", "const_storageAccountType": "Standard_LRS", - "const_subnetPrefix": "10.0.0.0/24", - "const_vmSize": "[parameters('vmSizeSelect')]", + "const_subnetPrefix": "[parameters('subnetPrefix')]", + "const_vmSize": "[parameters('vmSize')]", "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", "const_mountPointPath": "[concat('/mnt/', variables('name_share'))]", "name_linuxImageOfferSKU": "[first(split(parameters('skuUrnVersion'), ';'))]", "name_linuxImageVersion": "[last(split(parameters('skuUrnVersion'),';'))]", - "name_networkSecurityGroup": "[concat(parameters('dnsLabelPrefix'), '-nsg')]", - "name_nic": "adminServerVM_NIC", - "name_publicIPAddress": "adminServerVM_PublicIP", + "name_nic": "[concat('adminServerVM_NIC_', parameters('_globalResourceNameSuffix'))]", + "name_nic_with_pub_ip": "[concat(variables('name_nic'), '_with_pub_ip')]", + "name_nic_without_pub_ip": "[concat(variables('name_nic'), '_without_pub_ip')]", + "name_publicIPAddress": "[concat('adminServerVM_PublicIP_', parameters('_globalResourceNameSuffix'))]", + "name_privateSaEndpoint": "[concat('saep', parameters('_globalResourceNameSuffix'))]", "name_scriptFile": "setupAdminDomain.sh", - "name_storageAccount": "[concat(take(replace(parameters('guidValue'),'-',''),6),'olvm')]", - "name_share": "wlsshare", - "name_subnet": "Subnet", - "name_virtualNetwork": "[concat(parameters('wlsDomainName'),'_VNET')]", - "ref_networkSecurityGroup": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('name_networkSecurityGroup'))]", - "ref_subnet": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]", + "name_storageAccount": "[concat('olvmstg', parameters('_globalResourceNameSuffix'))]", + "name_share": "[concat('wlsshare', parameters('_globalResourceNameSuffix'))]", + "name_subnet": "[parameters('subnetName')]", + "name_virtualNetwork": "[parameters('virtualNetworkName')]", + "ref_networkSecurityGroup": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('nsgName'))]", + "ref_subnet": "[resourceId(parameters('virtualNetworkResourceGroupName'), 'Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]", "ref_storage": "[resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount'))]", "ref_fileService": "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('name_storageAccount'), 'default')]", - "ref_fileShare": "[resourceId('Microsoft.Storage/storageAccounts/fileServices/shares', variables('name_storageAccount'), 'default',variables('name_share'))]" + "ref_fileShare": "[resourceId('Microsoft.Storage/storageAccounts/fileServices/shares', variables('name_storageAccount'), 'default',variables('name_share'))]", + "name_customHostnameGeneratorscriptFile": "generateCustomHostNameVerifier.sh", + "name_customHostnameVerifierJavaFile": "src/main/java/WebLogicCustomHostNameVerifier.java", + "name_customHostnameValuesTemplate": "src/main/java/HostNameValuesTemplate.txt", + "name_customHostnameVerifierTest" : "src/test/java/WebLogicCustomHostNameVerifierTest.java" }, "resources": [ { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "name": "${admin.admin.start}", "properties": { "mode": "Incremental", @@ -205,8 +293,10 @@ }, { "type": "Microsoft.Network/networkSecurityGroups", - "apiVersion": "${azure.apiVersion}", - "name": "[variables('name_networkSecurityGroup')]", + "apiVersion": "${azure.apiVersionForNetworkSecurityGroups}", + "tags": "[parameters('tagsByResource')['${identifier.networkSecurityGroups}']]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", + "name": "[parameters('nsgName')]", "location": "[parameters('location')]", "properties": { "securityRules": [ @@ -254,23 +344,50 @@ }, { "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "${azure.apiVersion2}", + "apiVersion": "${azure.apiVersionForStorage}", + "tags": "[parameters('tagsByResource')['${identifier.storageAccounts}']]", "name": "[variables('name_storageAccount')]", "location": "[parameters('location')]", "sku": { "name": "[variables('const_storageAccountType')]" }, - "kind": "Storage", + "kind": "StorageV2", "properties": { "supportsHttpsTrafficOnly": false }, "dependsOn": [ - "[variables('name_networkSecurityGroup')]" + "[parameters('nsgName')]" + ] + }, + { + "apiVersion": "${azure.apiVersionForPrivateEndpoint}", + "name": "[variables('name_privateSaEndpoint')]", + "type": "Microsoft.Network/privateEndpoints", + "tags": "[parameters('tagsByResource')['${identifier.privateEndpoints}']]", + "location": "[parameters('location')]", + "properties": { + "privateLinkServiceConnections": [ + { + "name": "[variables('name_privateSaEndpoint')]", + "properties": { + "privateLinkServiceId": "[resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount'))]", + "groupIds": [ + "file" + ] + } + } + ], + "subnet": { + "id": "[variables('ref_subnet')]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount'))]" ] }, { "type": "Microsoft.Storage/storageAccounts/fileServices", - "apiVersion": "2019-06-01", + "apiVersion": "${azure.apiVersionForStorageFileService}", "name": "[concat(variables('name_storageAccount'), '/default')]", "dependsOn": [ "[variables('ref_storage')]" @@ -282,7 +399,7 @@ }, { "type": "Microsoft.Storage/storageAccounts/fileServices/shares", - "apiVersion": "2019-06-01", + "apiVersion": "${azure.apiVersionForStorageFileService}", "name": "[concat(variables('name_storageAccount'), '/default/', variables('name_share'))]", "dependsOn": [ "[variables('ref_fileService')]", @@ -293,8 +410,9 @@ } }, { + "apiVersion": "${azure.apiVersionForPublicIPAddresses}", "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "${azure.apiVersion}", + "tags": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'),parameters('tagsByResource')['${identifier.publicIPAddresses}'],if(empty(parameters('tagsByResource')['${identifier.publicIPAddresses}']),createObject(parameters('const_guidTag'),''),union(parameters('tagsByResource')['${identifier.publicIPAddresses}'],createObject(parameters('const_guidTag'),''))))]", "name": "[variables('name_publicIPAddress')]", "location": "[parameters('location')]", "properties": { @@ -305,8 +423,10 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualNetworks}", "type": "Microsoft.Network/virtualNetworks", - "apiVersion": "${azure.apiVersion}", + "tags": "[parameters('tagsByResource')['${identifier.virtualNetworks}']]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", "name": "[variables('name_virtualNetwork')]", "location": "[parameters('location')]", "dependsOn": [ @@ -314,9 +434,7 @@ ], "properties": { "addressSpace": { - "addressPrefixes": [ - "[variables('const_addressPrefix')]" - ] + "addressPrefixes": "[variables('const_addressPrefix')]" }, "subnets": [ { @@ -332,9 +450,11 @@ } }, { + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "${azure.apiVersion}", - "name": "[variables('name_nic')]", + "tags": "[parameters('tagsByResource')['${identifier.networkInterfaces}']]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", + "name": "[variables('name_nic_with_pub_ip')]", "location": "[parameters('location')]", "dependsOn": [ "[resourceId('Microsoft.Network/publicIPAddresses/', variables('name_publicIPAddress'))]", @@ -361,13 +481,43 @@ } }, { + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", + "type": "Microsoft.Network/networkInterfaces", + "tags": "[parameters('tagsByResource')['${identifier.networkInterfaces}']]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'existing')]", + "name": "[variables('name_nic_without_pub_ip')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Network/publicIPAddresses/', variables('name_publicIPAddress'))]", + "[resourceId('Microsoft.Network/virtualNetworks/', variables('name_virtualNetwork'))]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('name_publicIPAddress'))]" + }, + "subnet": { + "id": "[variables('ref_subnet')]" + } + } + } + ] + } + }, + { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "${azure.apiVersion}", + "tags": "[parameters('tagsByResource')['${identifier.virtualMachines}']]", "name": "[parameters('adminVMName')]", "location": "[parameters('location')]", "dependsOn": [ "[resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount'))]", - "[resourceId('Microsoft.Network/networkInterfaces/', variables('name_nic'))]" + "[resourceId('Microsoft.Network/networkInterfaces/', variables('name_nic_with_pub_ip'))]", + "[resourceId('Microsoft.Network/networkInterfaces/', variables('name_nic_without_pub_ip'))]" ], "identity": "[if(parameters('useSystemAssignedManagedIdentity'), json('{\"type\":\"SystemAssigned\"}'), null())]", "properties": { @@ -392,29 +542,19 @@ "managedDisk": { "storageAccountType": "Standard_LRS" } - }, - "dataDisks": [ - { - "lun": 0, - "createOption": "FromImage", - "diskSizeGB": 900, - "managedDisk": { - "storageAccountType": "Standard_LRS" - } - } - ] + } }, "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces',variables('name_nic'))]" + "id": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), resourceId('Microsoft.Network/networkInterfaces', variables('name_nic_with_pub_ip')), resourceId('Microsoft.Network/networkInterfaces', variables('name_nic_without_pub_ip')))]" } ] }, "diagnosticsProfile": { "bootDiagnostics": { "enabled": true, - "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount')), '${azure.apiVersion2}').primaryEndpoints.blob]" + "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount')), '${azure.apiVersionForStorage}').primaryEndpoints.blob]" } } }, @@ -426,12 +566,14 @@ }, { "name": "[concat(parameters('adminVMName'),'/newuserscript')]", + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", + "tags": "[parameters('tagsByResource')['${identifier.virtualMachinesExtensions}']]", "location": "[parameters('location')]", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachines/', parameters('adminVMName'))]", - "[variables('ref_fileShare')]" + "[variables('ref_fileShare')]", + "[variables('name_privateSaEndpoint')]" ], "properties": { "publisher": "Microsoft.Azure.Extensions", @@ -440,18 +582,23 @@ "autoUpgradeMinorVersion": true, "settings": { "fileUris": [ - "[uri(parameters('_artifactsLocationAdminTemplate'), concat('../scripts/', variables('name_scriptFile'), parameters('_artifactsLocationSasToken')))]" + "[uri(parameters('_artifactsLocationAdminTemplate'), concat('../scripts/', variables('name_scriptFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationAdminTemplate'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameGeneratorscriptFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationAdminTemplate'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierJavaFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationAdminTemplate'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameValuesTemplate'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationAdminTemplate'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierTest'), parameters('_artifactsLocationSasToken')))]" ] }, "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'),' <<< \"',parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('adminVMName'),' ', variables('const_wlsHome'),' ',variables('name_storageAccount'),' ',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount')), '2019-04-01').keys[0].value,' ',variables('const_mountPointPath'),' ',string(parameters('enableHTTPAdminListenPort')),' ', if(parameters('enableCustomDNS'), parameters('customDNSName'), reference(variables('name_publicIPAddress')).dnsSettings.fqdn), '\"')]" + "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'),' <<< \"',parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('adminVMName'),' ', variables('const_wlsHome'),' ',variables('name_storageAccount'),' ',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount')), '${azure.apiVersionForStorage}').keys[0].value,' ',variables('const_mountPointPath'),' ',string(parameters('enableHTTPAdminListenPort')),' ', if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), if(parameters('enableCustomDNS'), parameters('customDNSName'), reference(variables('name_publicIPAddress')).dnsSettings.fqdn), reference(variables('name_nic_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),' ',parameters('dnsLabelPrefix'),' ',parameters('location'),' ',parameters('virtualNetworkNewOrExisting'),' ',reference(resourceId('Microsoft.Network/privateEndpoints/', variables('name_privateSaEndpoint')), '${azure.apiVersionForPrivateEndpoint}').customDnsConfigs[0].ipAddresses[0],' ',variables('name_share'), '\"')]" } } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${admin.admin.end}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" ], @@ -467,9 +614,10 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-122130-jdk8-ol74}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122130-jdk8-ol74'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141200-jdk21-ol94}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk21-ol94'), bool('true'), bool('false'))]", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" ], @@ -485,9 +633,10 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-122130-jdk8-ol73}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'from.owls-122130-jdk8-ol73'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141200-jdk21-ol810}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk21-ol810'), bool('true'), bool('false'))]", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" ], @@ -503,9 +652,10 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-122140-jdk8-ol76}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'from.owls-122140-jdk8-ol76'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141200-jdk17-ol94}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk17-ol94'), bool('true'), bool('false'))]", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" ], @@ -521,9 +671,10 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-141100-jdk8-ol76}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol76'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141200-jdk17-ol810}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk17-ol810'), bool('true'), bool('false'))]", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" ], @@ -539,9 +690,10 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-141100-jdk11-ol76}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol76'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk11-ol91}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol91'), bool('true'), bool('false'))]", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" ], @@ -554,21 +706,172 @@ ] } } - } - + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk11-ol87}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol87'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk8-ol91}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol91'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk8-ol87}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol87'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-122140-jdk8-ol91}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-ol91'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-122140-jdk8-ol87}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-ol87'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk11-rhel87}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-rhel87'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-122140-jdk8-rhel87}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-rhel87'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk8-rhel87}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-rhel87'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + } ], "outputs": { "_adminPublicIPId": { "type": "string", - "value": "[resourceId('Microsoft.Network/publicIPAddresses',variables('name_publicIPAddress'))]" + "value": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), resourceId('Microsoft.Network/publicIPAddresses',variables('name_publicIPAddress')), reference(variables('name_nic_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress)]" }, "hostname": { "type": "string", - "value": "[reference(variables('name_publicIPAddress')).dnsSettings.fqdn]" + "value": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), reference(variables('name_publicIPAddress')).dnsSettings.fqdn, reference(variables('name_nic_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress)]" }, "sshCommand": { "type": "string", - "value": "[concat('ssh ', parameters('adminUsername'), '@', reference(variables('name_publicIPAddress')).dnsSettings.fqdn)]" + "value": "[concat('ssh ', parameters('adminUsername'), '@', if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), reference(variables('name_publicIPAddress')).dnsSettings.fqdn, reference(variables('name_nic_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress))]" }, "wlsDomainLocation": { "type": "string", @@ -576,11 +879,19 @@ }, "adminConsoleURL": { "type": "string", - "value": "[concat('http://',reference(variables('name_publicIPAddress')).dnsSettings.fqdn,':7001/console')]" + "value": "[uri(concat('http://', if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), reference(variables('name_publicIPAddress')).dnsSettings.fqdn, reference(variables('name_nic_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7001/console/'), '')]" }, "adminConsoleSecureURL": { "type": "string", - "value": "[concat('https://',reference(variables('name_publicIPAddress')).dnsSettings.fqdn,':7002/console')]" - } + "value": "[uri(concat('https://',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), reference(variables('name_publicIPAddress')).dnsSettings.fqdn, reference(variables('name_nic_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7002/console/'), '')]" + }, + "adminRemoteConsoleURL": { + "type": "string", + "value": "[uri(concat('http://', if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), reference(variables('name_publicIPAddress')).dnsSettings.fqdn, reference(variables('name_nic_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7001'), '')]" + }, + "adminRemoteConsoleSecureURL": { + "type": "string", + "value": "[uri(concat('https://',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), reference(variables('name_publicIPAddress')).dnsSettings.fqdn, reference(variables('name_nic_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7002'), '')]" + } } } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/adminTemplateForCustomSSL.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/adminTemplateForCustomSSL.json index 4d384a43b..695281585 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/adminTemplateForCustomSSL.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/adminTemplateForCustomSSL.json @@ -21,6 +21,18 @@ "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." } }, + "_globalResourceNameSuffix": { + "type": "string", + "metadata": { + "description": "A unique suffix that was specified during the deployment of the solution template." + } + }, + "const_guidTag" :{ + "type": "string", + "metadata": { + "description": "A unique tag for resources." + } + }, "adminPasswordOrKey": { "type": "securestring", "metadata": { @@ -89,51 +101,57 @@ "type": "string", "defaultValue": "[newGuid()]" }, - "keyVaultCustomIdentityKeyStoreData": { + "nsgName": { + "type": "string", + "metadata": { + "description": "Network Security Group name" + } + }, + "sslCustomIdentityKeyStoreData": { "type": "securestring", "metadata": { "description": "Weblogic Custom Identity Keystore Data" } }, - "keyVaultCustomIdentityKeyStorePassPhrase": { + "sslCustomIdentityKeyStorePassPhrase": { "type": "securestring", "metadata": { "description": "Weblogic Custom Identity Keystore Passphrase" } }, - "keyVaultCustomIdentityKeyStoreType": { + "sslCustomIdentityKeyStoreType": { "type": "string", "metadata": { "description": "Weblogic Custom Identity Keystore Type" }, "defaultValue": "JKS" }, - "keyVaultCustomTrustKeyStoreData": { + "sslCustomTrustKeyStoreData": { "type": "securestring", "metadata": { "description": "Weblogic Custom Trust Store Data" } }, - "keyVaultCustomTrustKeyStorePassPhrase": { + "sslCustomTrustKeyStorePassPhrase": { "type": "securestring", "metadata": { "description": "Weblogic Custom Trust Store Passphrase" } }, - "keyVaultCustomTrustKeyStoreType": { + "sslCustomTrustKeyStoreType": { "type": "string", "metadata": { "description": "Weblogic Custom Trust Store Type" }, "defaultValue": "JKS" }, - "keyVaultPrivateKeyAlias": { + "sslPrivateKeyAlias": { "type": "string", "metadata": { "description": "Weblogic Server Private Key Alias" } }, - "keyVaultPrivateKeyPassPhrase": { + "sslPrivateKeyPassPhrase": { "type": "securestring", "metadata": { "description": "Weblogic Server Private Key Pass Phrase" @@ -154,13 +172,21 @@ }, "skuUrnVersion": { "type": "string", - "defaultValue": "owls-122130-8u131-ol74;Oracle:weblogic-122130-jdk8u131-ol74:owls-122130-8u131-ol7;latest", + "defaultValue": "owls-141200-jdk21-ol94;Oracle:weblogic-141200-jdk21-ol94:owls-141200-jdk21-ol94;latest", "allowedValues": [ - "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest", - "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest", - "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest", - "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest", - "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" + "owls-141200-jdk21-ol94;Oracle:weblogic-141200-jdk21-ol94:owls-141200-jdk21-ol94;latest", + "owls-141200-jdk21-ol810;Oracle:weblogic-141200-jdk21-ol810:owls-141200-jdk21-ol810;latest", + "owls-141200-jdk17-ol94;Oracle:weblogic-141200-jdk17-ol94:owls-141200-jdk17-ol94;latest", + "owls-141200-jdk17-ol810;Oracle:weblogic-141200-jdk17-ol810:owls-141200-jdk17-ol810;latest", + "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", + "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest", + "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest", + "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest", + "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest", + "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest", + "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest", + "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest" ], "metadata": { "description": "The Oracle Linux image with Weblogic and Java preinstalled. Semicolon separated string of Sku, URN, and Version" @@ -180,7 +206,62 @@ "description": "Bool value, if it's set to true, a system assigned managed identity will to be created for the VM(s)" } }, - "vmSizeSelect": { + "virtualNetworkNewOrExisting": { + "type": "string", + "defaultValue": "new", + "allowedValues": [ + "new", + "existing" + ], + "metadata": { + "description": "Specify whether to create a new or existing virtual network for the VM." + } + }, + "virtualNetworkName": { + "type": "string", + "defaultValue": "wls-vnet", + "metadata": { + "description": "Name of the existing or new VNET" + } + }, + "virtualNetworkResourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "Resource group of Virtual network" + } + }, + "addressPrefixes": { + "type": "array", + "defaultValue": [ + "10.0.0.0/28" + ], + "metadata": { + "description": "Address prefix of the VNET." + } + }, + "subnetName": { + "type": "string", + "defaultValue": "wls-subnet", + "metadata": { + "description": "Name of the existing or new Subnet" + } + }, + "subnetPrefix": { + "type": "string", + "defaultValue": "10.0.0.0/29", + "metadata": { + "description": "Address prefix of the subnet" + } + }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, + "vmSize": { "type": "string", "defaultValue": "Standard_A3", "metadata": { @@ -207,7 +288,7 @@ } }, "variables": { - "const_addressPrefix": "10.0.0.0/16", + "const_addressPrefix": "[parameters('addressPrefixes')]", "const_hyphen": "-", "const_imageOffer": "[concat('weblogic',variables('const_hyphen'), split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[1],variables('const_hyphen'),split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[2],variables('const_hyphen'),split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[3],if(parameters('usePreviewImage'),'-preview',''))]", "const_imagePublisher": "oracle", @@ -226,30 +307,37 @@ "const_publicIPAddressType": "Dynamic", "const_requiredPortrange": ",65200-65535,5556", "const_storageAccountType": "Standard_LRS", - "const_subnetPrefix": "10.0.0.0/24", - "const_vmSize": "[parameters('vmSizeSelect')]", + "const_subnetPrefix": "[parameters('subnetPrefix')]", + "const_vmSize": "[parameters('vmSize')]", "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", "name_linuxImageOfferSKU": "[first(split(parameters('skuUrnVersion'), ';'))]", "name_linuxImageVersion": "[last(split(parameters('skuUrnVersion'),';'))]", - "name_networkSecurityGroup": "[concat(parameters('dnsLabelPrefix'), '-nsg')]", - "name_nic": "adminServerVM_NIC", - "name_publicIPAddress": "adminServerVM_PublicIP", + "name_nic": "[concat('adminServerVM_NIC_', parameters('_globalResourceNameSuffix'))]", + "name_nic_with_pub_ip": "[concat(variables('name_nic'), '_with_pub_ip')]", + "name_nic_without_pub_ip": "[concat(variables('name_nic'), '_without_pub_ip')]", + "name_publicIPAddress": "[concat('adminServerVM_PublicIP_', parameters('_globalResourceNameSuffix'))]", + "name_privateSaEndpoint": "[concat(take(replace(parameters('guidValue'),'-',''),6),'saep')]", "name_scriptFile": "setupAdminDomain.sh", - "name_storageAccount": "[concat(take(replace(parameters('guidValue'),'-',''),6),'olvm')]", - "name_subnet": "Subnet", - "name_share": "wlsshare", - "name_virtualNetwork": "[concat(parameters('wlsDomainName'),'_VNET')]", - "ref_networkSecurityGroup": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('name_networkSecurityGroup'))]", - "ref_subnet": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]", + "name_storageAccount": "[concat('olvmstg', parameters('_globalResourceNameSuffix'))]", + "name_subnet": "[parameters('subnetName')]", + "name_share": "[concat('wlsshare', parameters('_globalResourceNameSuffix'))]", + "name_virtualNetwork": "[parameters('virtualNetworkName')]", + "ref_networkSecurityGroup": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('nsgName'))]", + "ref_subnet": "[resourceId(parameters('virtualNetworkResourceGroupName'), 'Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]", "ref_storage": "[resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount'))]", "ref_fileService": "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('name_storageAccount'), 'default')]", - "ref_fileShare": "[resourceId('Microsoft.Storage/storageAccounts/fileServices/shares', variables('name_storageAccount'), 'default',variables('name_share'))]" + "ref_fileShare": "[resourceId('Microsoft.Storage/storageAccounts/fileServices/shares', variables('name_storageAccount'), 'default',variables('name_share'))]", + "name_customHostnameGeneratorscriptFile": "generateCustomHostNameVerifier.sh", + "name_customHostnameVerifierJavaFile": "src/main/java/WebLogicCustomHostNameVerifier.java", + "name_customHostnameValuesTemplate": "src/main/java/HostNameValuesTemplate.txt", + "name_customHostnameVerifierTest" : "src/test/java/WebLogicCustomHostNameVerifierTest.java" }, "resources": [ { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${admin.admin.start}", "type": "Microsoft.Resources/deployments", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "properties": { "mode": "Incremental", "template": { @@ -261,9 +349,26 @@ } }, { + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${admin.ssl.start}", + "type": "Microsoft.Resources/deployments", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "apiVersion": "${azure.apiVersionForNetworkSecurityGroups}", "type": "Microsoft.Network/networkSecurityGroups", - "apiVersion": "${azure.apiVersion}", - "name": "[variables('name_networkSecurityGroup')]", + "tags": "[parameters('tagsByResource')['${identifier.networkSecurityGroups}']]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", + "name": "[parameters('nsgName')]", "location": "[parameters('location')]", "properties": { "securityRules": [ @@ -311,23 +416,50 @@ }, { "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "${azure.apiVersion2}", + "apiVersion": "${azure.apiVersionForStorage}", "name": "[variables('name_storageAccount')]", + "tags": "[parameters('tagsByResource')['${identifier.storageAccounts}']]", "location": "[parameters('location')]", "sku": { "name": "[variables('const_storageAccountType')]" }, - "kind": "Storage", + "kind": "StorageV2", "properties": { "supportsHttpsTrafficOnly": false }, "dependsOn": [ - "[variables('name_networkSecurityGroup')]" + "[parameters('nsgName')]" + ] + }, + { + "apiVersion": "${azure.apiVersionForPrivateEndpoint}", + "name": "[variables('name_privateSaEndpoint')]", + "type": "Microsoft.Network/privateEndpoints", + "tags": "[parameters('tagsByResource')['${identifier.privateEndpoints}']]", + "location": "[parameters('location')]", + "properties": { + "privateLinkServiceConnections": [ + { + "name": "[variables('name_privateSaEndpoint')]", + "properties": { + "privateLinkServiceId": "[resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount'))]", + "groupIds": [ + "file" + ] + } + } + ], + "subnet": { + "id": "[variables('ref_subnet')]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount'))]" ] }, { "type": "Microsoft.Storage/storageAccounts/fileServices", - "apiVersion": "${azure.apiVersion2}", + "apiVersion": "${azure.apiVersionForStorageFileService}", "name": "[concat(variables('name_storageAccount'), '/default')]", "dependsOn": [ "[variables('ref_storage')]" @@ -339,7 +471,7 @@ }, { "type": "Microsoft.Storage/storageAccounts/fileServices/shares", - "apiVersion": "${azure.apiVersion2}", + "apiVersion": "${azure.apiVersionForStorageFileService}", "name": "[concat(variables('name_storageAccount'), '/default/', variables('name_share'))]", "dependsOn": [ "[variables('ref_fileService')]", @@ -350,8 +482,9 @@ } }, { + "apiVersion": "${azure.apiVersionForPublicIPAddresses}", "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "${azure.apiVersion}", + "tags": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'),parameters('tagsByResource')['${identifier.publicIPAddresses}'],if(empty(parameters('tagsByResource')['${identifier.publicIPAddresses}']),createObject(parameters('const_guidTag'),''),union(parameters('tagsByResource')['${identifier.publicIPAddresses}'],createObject(parameters('const_guidTag'),''))))]", "name": "[variables('name_publicIPAddress')]", "location": "[parameters('location')]", "properties": { @@ -360,10 +493,12 @@ "domainNameLabel": "[concat(toLower(parameters('dnsLabelPrefix')),'-',take(replace(parameters('guidValue'), '-', ''), 10),'-',toLower(parameters('wlsDomainName')))]" } } - }, + }, { + "apiVersion": "${azure.apiVersionForVirtualNetworks}", "type": "Microsoft.Network/virtualNetworks", - "apiVersion": "${azure.apiVersion}", + "tags": "[parameters('tagsByResource')['${identifier.virtualNetworks}']]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", "name": "[variables('name_virtualNetwork')]", "location": "[parameters('location')]", "dependsOn": [ @@ -371,9 +506,7 @@ ], "properties": { "addressSpace": { - "addressPrefixes": [ - "[variables('const_addressPrefix')]" - ] + "addressPrefixes": "[variables('const_addressPrefix')]" }, "subnets": [ { @@ -389,9 +522,11 @@ } }, { + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "${azure.apiVersion}", - "name": "[variables('name_nic')]", + "tags": "[parameters('tagsByResource')['${identifier.networkInterfaces}']]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", + "name": "[variables('name_nic_with_pub_ip')]", "location": "[parameters('location')]", "dependsOn": [ "[resourceId('Microsoft.Network/publicIPAddresses/', variables('name_publicIPAddress'))]", @@ -418,14 +553,43 @@ } }, { + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", + "type": "Microsoft.Network/networkInterfaces", + "tags": "[parameters('tagsByResource')['${identifier.networkInterfaces}']]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'existing')]", + "name": "[variables('name_nic_without_pub_ip')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Network/publicIPAddresses/', variables('name_publicIPAddress'))]", + "[resourceId('Microsoft.Network/virtualNetworks/', variables('name_virtualNetwork'))]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('name_publicIPAddress'))]" + }, + "subnet": { + "id": "[variables('ref_subnet')]" + } + } + } + ] + } + }, + { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "${azure.apiVersion}", + "tags": "[parameters('tagsByResource')['${identifier.virtualMachines}']]", "name": "[parameters('adminVMName')]", "location": "[parameters('location')]", "dependsOn": [ "[resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount'))]", - "[resourceId('Microsoft.Network/networkInterfaces/', variables('name_nic'))]" - ], + "[resourceId('Microsoft.Network/networkInterfaces/', variables('name_nic_with_pub_ip'))]", + "[resourceId('Microsoft.Network/networkInterfaces/', variables('name_nic_without_pub_ip'))]" ], "identity": "[if(parameters('useSystemAssignedManagedIdentity'), json('{\"type\":\"SystemAssigned\"}'), null())]", "properties": { "hardwareProfile": { @@ -449,29 +613,19 @@ "managedDisk": { "storageAccountType": "Standard_LRS" } - }, - "dataDisks": [ - { - "lun": 0, - "createOption": "FromImage", - "diskSizeGB": 900, - "managedDisk": { - "storageAccountType": "Standard_LRS" - } - } - ] + } }, "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces',variables('name_nic'))]" + "id": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), resourceId('Microsoft.Network/networkInterfaces', variables('name_nic_with_pub_ip')), resourceId('Microsoft.Network/networkInterfaces', variables('name_nic_without_pub_ip')))]" } ] }, "diagnosticsProfile": { "bootDiagnostics": { "enabled": true, - "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount')), '${azure.apiVersion2}').primaryEndpoints.blob]" + "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount')), '${azure.apiVersionForStorage}').primaryEndpoints.blob]" } } }, @@ -482,13 +636,15 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines/extensions", + "tags": "[parameters('tagsByResource')['${identifier.virtualMachinesExtensions}']]", "name": "[concat(parameters('adminVMName'),'/newuserscript')]", - "apiVersion": "${azure.apiVersion}", "location": "[parameters('location')]", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachines/', parameters('adminVMName'))]", - "[variables('ref_fileShare')]" + "[variables('ref_fileShare')]", + "[variables('name_privateSaEndpoint')]" ], "properties": { "publisher": "Microsoft.Azure.Extensions", @@ -497,18 +653,40 @@ "autoUpgradeMinorVersion": true, "settings": { "fileUris": [ - "[uri(parameters('_artifactsLocationAdminTemplate'), concat('../scripts/', variables('name_scriptFile'), parameters('_artifactsLocationSasToken')))]" + "[uri(parameters('_artifactsLocationAdminTemplate'), concat('../scripts/', variables('name_scriptFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationAdminTemplate'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameGeneratorscriptFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationAdminTemplate'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierJavaFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationAdminTemplate'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameValuesTemplate'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationAdminTemplate'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierTest'), parameters('_artifactsLocationSasToken')))]" ] }, "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'),' <<< \"',parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('adminVMName'),' ', variables('const_wlsHome'),' ',variables('name_storageAccount'),' ',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount')), '${azure.apiVersion2}').keys[0].value,' ',variables('const_mountPointPath'),' ',string(parameters('enableHTTPAdminListenPort')),' ',if(parameters('enableCustomDNS'), parameters('customDNSName'), reference(variables('name_publicIPAddress')).dnsSettings.fqdn),' ',string(parameters('enableCustomSSL')),' ',if(parameters('enableCustomSSL'),base64(parameters('keyVaultCustomIdentityKeyStoreData')),''),' ',if(parameters('enableCustomSSL'),base64(parameters('keyVaultCustomIdentityKeyStorePassPhrase')),''),' ',if(parameters('enableCustomSSL'),base64(parameters('keyVaultCustomIdentityKeyStoreType')),''),' ',if(parameters('enableCustomSSL'),base64(parameters('keyVaultCustomTrustKeyStoreData')),''),' ',if(parameters('enableCustomSSL'),base64(parameters('keyVaultCustomTrustKeyStorePassPhrase')),''),' ',if(parameters('enableCustomSSL'),base64(parameters('keyVaultCustomTrustKeyStoreType')),''),' ',if(parameters('enableCustomSSL'),base64(parameters('keyVaultPrivateKeyAlias')),''),' ',if(parameters('enableCustomSSL'),base64(parameters('keyVaultPrivateKeyPassPhrase')),''),'\"')]" + "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'),' <<< \"',parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('adminVMName'),' ', variables('const_wlsHome'),' ',variables('name_storageAccount'),' ',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount')), '${azure.apiVersionForStorage}').keys[0].value,' ',variables('const_mountPointPath'),' ',string(parameters('enableHTTPAdminListenPort')),' ',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), if(parameters('enableCustomDNS'), parameters('customDNSName'), reference(variables('name_publicIPAddress')).dnsSettings.fqdn), reference(variables('name_nic_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),' ',parameters('dnsLabelPrefix'),' ',parameters('location'),' ',parameters('virtualNetworkNewOrExisting'),' ',reference(resourceId('Microsoft.Network/privateEndpoints/', variables('name_privateSaEndpoint')), '${azure.apiVersionForPrivateEndpoint}').customDnsConfigs[0].ipAddresses[0],' ',variables('name_share'),' ',string(parameters('enableCustomSSL')),' ',if(parameters('enableCustomSSL'),base64(parameters('sslCustomIdentityKeyStoreData')),''),' ',if(parameters('enableCustomSSL'),base64(parameters('sslCustomIdentityKeyStorePassPhrase')),''),' ',if(parameters('enableCustomSSL'),base64(parameters('sslCustomIdentityKeyStoreType')),''),' ',if(parameters('enableCustomSSL'),base64(parameters('sslCustomTrustKeyStoreData')),''),' ',if(parameters('enableCustomSSL'),base64(parameters('sslCustomTrustKeyStorePassPhrase')),''),' ',if(parameters('enableCustomSSL'),base64(parameters('sslCustomTrustKeyStoreType')),''),' ',if(parameters('enableCustomSSL'),base64(parameters('sslPrivateKeyAlias')),''),' ',if(parameters('enableCustomSSL'),base64(parameters('sslPrivateKeyPassPhrase')),''), '\"')]" } + } + }, + { + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${admin.ssl.end}", + "type": "Microsoft.Resources/deployments", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] } } }, { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${admin.admin.end}", "type": "Microsoft.Resources/deployments", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" ], @@ -524,9 +702,10 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-122130-jdk8-ol74}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122130-jdk8-ol74'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141200-jdk21-ol94}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk21-ol94'), bool('true'), bool('false'))]", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" ], @@ -542,9 +721,10 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-122130-jdk8-ol73}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'from.owls-122130-jdk8-ol73'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141200-jdk21-ol810}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk21-ol810'), bool('true'), bool('false'))]", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" ], @@ -560,9 +740,10 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-122140-jdk8-ol76}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'from.owls-122140-jdk8-ol76'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141200-jdk17-ol94}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk17-ol94'), bool('true'), bool('false'))]", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" ], @@ -578,9 +759,10 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-141100-jdk8-ol76}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol76'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141200-jdk17-ol810}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk17-ol810'), bool('true'), bool('false'))]", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" ], @@ -596,9 +778,10 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-141100-jdk11-ol76}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol76'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk11-ol91}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol91'), bool('true'), bool('false'))]", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" ], @@ -611,20 +794,172 @@ ] } } - } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk11-ol87}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol87'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk8-ol91}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol91'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk8-ol87}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol87'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-122140-jdk8-ol91}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-ol91'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-122140-jdk8-ol87}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-ol87'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk11-rhel87}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-rhel87'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk8-rhel87}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-rhel87'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-122140-jdk8-rhel87}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-rhel87'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + } ], "outputs": { "_adminPublicIPId": { "type": "string", - "value": "[resourceId('Microsoft.Network/publicIPAddresses',variables('name_publicIPAddress'))]" + "value": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), resourceId('Microsoft.Network/publicIPAddresses',variables('name_publicIPAddress')), reference(variables('name_nic_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress)]" }, "hostname": { "type": "string", - "value": "[reference(variables('name_publicIPAddress')).dnsSettings.fqdn]" + "value": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), reference(variables('name_publicIPAddress')).dnsSettings.fqdn, reference(variables('name_nic_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress)]" }, "sshCommand": { "type": "string", - "value": "[concat('ssh ', parameters('adminUsername'), '@', reference(variables('name_publicIPAddress')).dnsSettings.fqdn)]" + "value": "[concat('ssh ', parameters('adminUsername'), '@', if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), reference(variables('name_publicIPAddress')).dnsSettings.fqdn, reference(variables('name_nic_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress))]" }, "wlsDomainLocation": { "type": "string", @@ -632,11 +967,19 @@ }, "adminConsoleURL": { "type": "string", - "value": "[concat('http://',reference(variables('name_publicIPAddress')).dnsSettings.fqdn,':7001/console')]" + "value": "[uri(concat('http://', if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), reference(variables('name_publicIPAddress')).dnsSettings.fqdn, reference(variables('name_nic_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7001/console/'), '')]" }, "adminConsoleSecureURL": { "type": "string", - "value": "[concat('https://',reference(variables('name_publicIPAddress')).dnsSettings.fqdn,':7002/console')]" - } + "value": "[uri(concat('https://',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), reference(variables('name_publicIPAddress')).dnsSettings.fqdn, reference(variables('name_nic_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7002/console/'), '')]" + }, + "adminRemoteConsoleURL": { + "type": "string", + "value": "[uri(concat('http://', if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), reference(variables('name_publicIPAddress')).dnsSettings.fqdn, reference(variables('name_nic_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7001'), '')]" + }, + "adminRemoteConsoleSecureURL": { + "type": "string", + "value": "[uri(concat('https://',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), reference(variables('name_publicIPAddress')).dnsSettings.fqdn, reference(variables('name_nic_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7002'), '')]" + } } } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/dbTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/dbTemplate.json index 1e174dffb..10d56c67c 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/dbTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/dbTemplate.json @@ -8,19 +8,12 @@ "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." } }, - "_artifactsLocationDbTemplate": { - "defaultValue": "[if(contains(parameters('_artifactsLocation'), 'githubusercontent'), parameters('_artifactsLocation'), deployment().properties.templateLink.uri)]", - "type": "string", - "metadata": { - "description": "If we are deploying from the command line, use the passed in _artifactsLocation, otherwise use the default." - } - }, "_artifactsLocationSasToken": { - "defaultValue": "", "type": "securestring", "metadata": { "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." - } + }, + "defaultValue": "" }, "adminVMName": { "type": "string", @@ -30,32 +23,57 @@ } }, "databaseType": { + "defaultValue": "", "type": "string", "metadata": { "description": "One of the supported database types" } }, + "dbGlobalTranPro": { + "defaultValue": "OnePhaseCommit", + "type": "string", + "metadata": { + "description": "Determines the transaction protocol (global transaction processing behavior) for the data source." + } + }, + "dbIdentity": { + "defaultValue": {}, + "type": "object", + "metadata": { + "description": "Managed identity that has access to the data source." + } + }, "dbPassword": { + "defaultValue": "[newGuid()]", "type": "securestring", "metadata": { "description": "Password for Database" } }, "dbUser": { + "defaultValue": "", "type": "string", "metadata": { "description": "Userid of Database" } }, "dsConnectionURL": { + "defaultValue": "", "type": "string", "metadata": { "description": "JDBC Connection String" } }, + "enablePswlessConnection": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "True to enable passwordless connection." + } + }, "jdbcDataSourceName": { - "type": "string", "defaultValue": "", + "type": "string", "metadata": { "description": "JNDI Name for JDBC Datasource" } @@ -66,6 +84,20 @@ "description": "Location for all resources." } }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, + "wlsDomainName": { + "type": "string", + "defaultValue": "adminDomain", + "metadata": { + "description": "Provide Weblogic domain name" + } + }, "wlsPassword": { "type": "securestring", "metadata": { @@ -80,118 +112,173 @@ } }, "variables": { - "const_wlsAdminPort": "7005", - "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", - "name_scriptFilePrefix": "datasourceConfig-", - "name_scriptFileSuffix-sqlserver": "sqlserver.sh", - "name_scriptFileSuffix-oracle": "oracle.sh", - "name_scriptFileSuffix-postgresql": "postgresql.sh" + "name_dbLinkedTemplateName": "_dbTemplate.json", + "name_dbPswlessTemplateName": "_pswlessDbTemplate.json", + "name_dbUpgradeMySQLDriver": "_installJdbcLibsTemplate.json" }, "resources": [ { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${admin.database.start}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "pswlessDbTemplate", + "condition": "[parameters('enablePswlessConnection')]", "properties": { "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(parameters('adminVMName'),'/newuserscript')]", - "location": "[parameters('location')]", - "properties": { - "publisher": "Microsoft.Azure.Extensions", - "type": "CustomScript", - "typeHandlerVersion": "2.0", - "autoUpgradeMinorVersion": true, - "settings": { - "fileUris": [ - "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-sqlserver'), parameters('_artifactsLocationSasToken')))]", - "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-oracle'), parameters('_artifactsLocationSasToken')))]", - "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-postgresql'), parameters('_artifactsLocationSasToken')))]" - ] + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_dbPswlessTemplateName')))]", + "contentVersion": "1.0.0.0" }, - "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptFilePrefix'),parameters('databaseType'),'.sh <<< \"',variables('const_wlsHome'),' ',parameters('adminVMName'),' ',variables('const_wlsAdminPort'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('jdbcDataSourceName'),' ',parameters('dsConnectionURL'),' ',parameters('dbUser'),' ',parameters('dbPassword'),'\"')]" + "parameters": { + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + }, + "adminVMName": { + "value": "[parameters('adminVMName')]" + }, + "databaseType": { + "value": "[parameters('databaseType')]" + }, + "dbGlobalTranPro": { + "value": "[parameters('dbGlobalTranPro')]" + }, + "dbIdentity": { + "value": "[parameters('dbIdentity')]" + }, + "dbUser": { + "value": "[parameters('dbUser')]" + }, + "dsConnectionURL": { + "value": "[parameters('dsConnectionURL')]" + }, + "jdbcDataSourceName": { + "value": "[parameters('jdbcDataSourceName')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "tagsByResource": { + "value": "[parameters('tagsByResource')]" + }, + "wlsDomainName": { + "value": "[parameters('wlsDomainName')]" + }, + "wlsPassword": { + "value": "[parameters('wlsPassword')]" + }, + "wlsUserName": { + "value": "[parameters('wlsUserName')]" + } } } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${admin.database.end}", - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" - ], + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "upgradeMySQLJdbcDriverTemplate", + "condition": "[and(not(parameters('enablePswlessConnection')), equals(parameters('databaseType'),'mysql'))]", "properties": { "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${database.oracle}", - "condition": "[if(contains(parameters('databaseType'), 'oracle'), bool('true'), bool('false'))]", - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" - ], - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${database.postgresql}", - "condition": "[if(contains(parameters('databaseType'), 'postgresql'), bool('true'), bool('false'))]", - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" - ], - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_dbUpgradeMySQLDriver')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + }, + "adminVMName": { + "value": "[parameters('adminVMName')]" + }, + "databaseType": { + "value": "[parameters('databaseType')]" + }, + "enablePswlessConnection": { + "value": "[parameters('enablePswlessConnection')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "tagsByResource": { + "value": "[parameters('tagsByResource')]" + }, + "wlsDomainName": { + "value": "[parameters('wlsDomainName')]" + }, + "wlsPassword": { + "value": "[parameters('wlsPassword')]" + }, + "wlsUserName": { + "value": "[parameters('wlsUserName')]" + } } } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${database.sqlserver}", - "condition": "[if(contains(parameters('databaseType'), 'sqlserver'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "passwordDatasourceDeployment", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[not(parameters('enablePswlessConnection'))]", "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + "[resourceId('Microsoft.Resources/deployments', 'upgradeMySQLJdbcDriverTemplate')]" ], "properties": { "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_dbLinkedTemplateName')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + }, + "adminVMName": { + "value": "[parameters('adminVMName')]" + }, + "databaseType": { + "value": "[parameters('databaseType')]" + }, + "dbGlobalTranPro": { + "value": "[parameters('dbGlobalTranPro')]" + }, + "dbPassword": { + "value": "[parameters('dbPassword')]" + }, + "dbUser": { + "value": "[parameters('dbUser')]" + }, + "dsConnectionURL": { + "value": "[parameters('dsConnectionURL')]" + }, + "enablePswlessConnection": { + "value": "[parameters('enablePswlessConnection')]" + }, + "jdbcDataSourceName": { + "value": "[parameters('jdbcDataSourceName')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "tagsByResource": { + "value": "[parameters('tagsByResource')]" + }, + "wlsPassword": { + "value": "[parameters('wlsPassword')]" + }, + "wlsUserName": { + "value": "[parameters('wlsUserName')]" + } } } } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/dnszonesTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/dnszonesTemplate.json index b950e1057..a850bc0a0 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/dnszonesTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/dnszonesTemplate.json @@ -15,6 +15,12 @@ "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." } }, + "_globalResourceNameSuffix": { + "type": "string", + "metadata": { + "description": "The suffix to be added to the globally unique resource name." + } + }, "dnszonesARecordSetNames": { "type": "array", "defaultValue": [], @@ -57,12 +63,6 @@ "description": "If true, update A records in the existing DNS Zone, otherwise, create a new DNS Zone and ." } }, - "identity": { - "type": "Object", - "metadata": { - "description": "Managed identity to be used for the deployment script. Currently, only user-assigned MSI is supported." - } - }, "location": { "type": "string", "metadata": { @@ -83,6 +83,13 @@ "description": "References to Azure resources from where the DNS resource value is taken. Each item is corresponding to values of dnszonesARecordSetNames." } }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, "ttl": { "type": "int", "defaultValue": 3600, @@ -105,22 +112,23 @@ }, "resources": [ { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${cluster.dns.start}", "type": "Microsoft.Resources/deployments", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "properties": { "mode": "Incremental", "template": { "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", - "resources": [ - ] + "resources": [] } } }, { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "type": "Microsoft.Resources/deployments", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "name": "createDNSZone", "condition": "[not(parameters('hasDNSZones'))]", "properties": { @@ -148,6 +156,9 @@ "targetResources": { "value": "[parameters('targetResources')]" }, + "tagsByResource": { + "value": "[parameters('tagsByResource')]" + }, "ttl": { "value": "[parameters('ttl')]" } @@ -155,8 +166,9 @@ } }, { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "type": "Microsoft.Resources/deployments", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "name": "updateDNSZone", "condition": "[parameters('hasDNSZones')]", "properties": { @@ -172,6 +184,9 @@ "_artifactsLocationSasToken": { "value": "[parameters('_artifactsLocationSasToken')]" }, + "_globalResourceNameSuffix": { + "value": "[parameters('_globalResourceNameSuffix')]" + }, "dnszonesARecordSetNames": { "value": "[parameters('dnszonesARecordSetNames')]" }, @@ -184,9 +199,6 @@ "dnszoneName": { "value": "[parameters('dnszoneName')]" }, - "identity": { - "value": "[parameters('identity')]" - }, "location": { "value": "[parameters('location')]" }, @@ -196,6 +208,9 @@ "targetResources": { "value": "[parameters('targetResources')]" }, + "tagsByResource": { + "value": "[parameters('tagsByResource')]" + }, "ttl": { "value": "[parameters('ttl')]" }, @@ -206,16 +221,16 @@ } }, { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${cluster.dns.end}", "type": "Microsoft.Resources/deployments", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "properties": { "mode": "Incremental", "template": { "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", - "resources": [ - ] + "resources": [] } } } @@ -224,7 +239,7 @@ "dnsZoneNameServers": { "type": "array", "condition": "[not(parameters('hasDNSZones'))]", - "value": "[reference('createDNSZone', '${azure.apiVersion}').outputs.dnsZoneNameServers.value]" + "value": "[reference('createDNSZone', '${azure.apiVersionForDeployment}').outputs.dnsZoneNameServers.value]" } } } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/elkNestedTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/elkNestedTemplate.json deleted file mode 100644 index 0ccfc595d..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/elkNestedTemplate.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "_artifactsLocation": { - "type": "string", - "metadata": { - "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." - } - }, - "_artifactsLocationELKTemplate": { - "defaultValue": "[if(contains(parameters('_artifactsLocation'), 'githubusercontent'), parameters('_artifactsLocation'), deployment().properties.templateLink.uri)]", - "type": "string", - "metadata": { - "description": "If we are deploying from the command line, use the passed in _artifactsLocation, otherwise use the default." - } - }, - "_artifactsLocationSasToken": { - "defaultValue": "", - "type": "securestring", - "metadata": { - "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." - } - }, - "adminVMName": { - "type": "string", - "defaultValue": "adminVM", - "metadata": { - "description": "Admin Server hosting VM name." - } - }, - "elasticsearchEndpoint": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Endpoint of the Elasticsearch instance." - } - }, - "elasticsearchPassword": { - "type": "securestring", - "defaultValue": "[newGuid()]", - "metadata": { - "description": "The credentials to distibute message with REST API to Elasticsearch instance." - } - }, - "elasticsearchUserName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "The credentials to distibute message with REST API to Elasticsearch instance." - } - }, - "guidValue": { - "type": "string", - "defaultValue": "[newGuid()]" - }, - "location": { - "type": "string", - "metadata": { - "description": "Location for all resources." - } - }, - "logsToIntegrate": { - "type": "array", - "defaultValue": [ "HTTPAccessLog", "ServerLog", "DomainLog", "DataSourceLog", "StandardErrorAndOutput" ], - "allowedValues": [ "HTTPAccessLog", "ServerLog", "DomainLog", "DataSourceLog", "StandardErrorAndOutput" ], - "metadata": { - "description": "Specify the expeted logs to integrate, you must input at least one log." - } - }, - "wlsDomainName": { - "type": "string", - "defaultValue": "adminDomain", - "metadata": { - "description": "Provide Weblogic domain name" - } - }, - "wlsPassword": { - "type": "securestring", - "metadata": { - "description": "Password for your Weblogic domain name" - } - }, - "wlsUserName": { - "type": "string", - "metadata": { - "description": "Username for your Weblogic domain name" - } - } - }, - "variables": { - "const_adminServerName": "admin", - "const_logIndex": "[concat('azure-weblogic-admin-', parameters('guidValue'))]", - "const_wlsAdminPort": "7005", - "const_wlsDomainPath": "[concat('/u01/domains/', parameters('wlsDomainName'))]", - "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", - "name_scriptELKConfiguration": "elkIntegration.sh" - }, - "functions": [ - { - "namespace": "array", - "members": { - "join": { - "parameters": [ - { - "name": "items", - "type": "array" - } - ], - "output": { - "type": "string", - "value": "[replace(replace(replace(string(parameters('items')), '[\"', ''), '\"]', ''), '\",\"', ',')]" - } - } - } - } - ], - "resources": [ - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${admin.elk.start}", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(parameters('adminVMName'),'/newuserscript')]", - "location": "[parameters('location')]", - "properties": { - "publisher": "Microsoft.Azure.Extensions", - "type": "CustomScript", - "typeHandlerVersion": "2.0", - "autoUpgradeMinorVersion": true, - "settings": { - "fileUris": [ - "[uri(parameters('_artifactsLocationELKTemplate'), concat('../scripts/', variables('name_scriptELKConfiguration'), parameters('_artifactsLocationSasToken')))]" - ] - }, - "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptELKConfiguration'),' <<< \"', variables('const_wlsHome'), ' ', parameters('adminVMName'), ' ', variables('const_wlsAdminPort'), ' ', parameters('wlsUserName'), ' ', parameters('wlsPassword'), ' ', variables('const_adminServerName'), ' ',parameters('elasticsearchEndpoint') ,' ', parameters('elasticsearchUserName'),' ', parameters('elasticsearchPassword'), ' ', parameters('wlsDomainName'),' ', variables('const_wlsDomainPath'),' ', array.join(parameters('logsToIntegrate')),' ', variables('const_logIndex'),'\"')]" - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${admin.elk.end}", - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" - ], - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - } - ], - "outputs": { - "artifactsLocationPassedIn": { - "type": "string", - "value": "[parameters('_artifactsLocation')]" - }, - "logIndex": { - "type": "string", - "value": "[variables('const_logIndex')]" - } - } -} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/nsgNestedTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/nsgNestedTemplate.json index 9b9363113..a2ec4c154 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/nsgNestedTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/nsgNestedTemplate.json @@ -18,10 +18,10 @@ }, "resources": [ { + "apiVersion": "${azure.apiVersionForNetworkSecurityGroups}", "type": "Microsoft.Network/networkSecurityGroups/securityRules", "name": "[concat(parameters('networkSecurityGroupName'),'/','WebLogicAdminPortsAllowed')]", "condition": "[not(parameters('denyPublicTrafficForAdminServer'))]", - "apiVersion": "${azure.apiVersion}", "properties": { "protocol": "TCP", "sourcePortRange": "*", @@ -37,10 +37,10 @@ } }, { + "apiVersion": "${azure.apiVersionForNetworkSecurityGroups}", "type": "Microsoft.Network/networkSecurityGroups/securityRules", "name": "[concat(parameters('networkSecurityGroupName'),'/','WebLogicAdminPortsDenied')]", "condition": "[parameters('denyPublicTrafficForAdminServer')]", - "apiVersion": "${azure.apiVersion}", "properties": { "protocol": "*", "sourcePortRange": "*", @@ -56,4 +56,4 @@ } } ] -} +} \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/postDeploymentTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/postDeploymentTemplate.json new file mode 100644 index 000000000..22eca42b8 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/postDeploymentTemplate.json @@ -0,0 +1,107 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "metadata": { + "description": "Location for all resources." + } + }, + "_globalResourceNameSuffix": { + "type": "string", + "metadata": { + "description": "A unique suffix that was specified during the deployment of the solution template." + } + }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, + "const_guidTag" :{ + "type": "string", + "metadata": { + "description": "A unique tag for resources." + } + }, + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." + } + }, + "_artifactsLocationAdminTemplate": { + "defaultValue": "[if(contains(parameters('_artifactsLocation'), 'githubusercontent'), parameters('_artifactsLocation'), deployment().properties.templateLink.uri)]", + "type": "string", + "metadata": { + "description": "If we are deploying from the command line, use the passed in _artifactsLocation, otherwise use the default." + } + }, + "_artifactsLocationSasToken": { + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." + } + }, + "userAssignedIdentityResourceId":{ + "type": "string", + "metadata": { + "Description": "UserAssigned Identity" + } + }, + "utcValue": { + "type": "string", + "defaultValue": "[utcNow()]" + } + }, + "variables": { + "name_postDeploymentscriptFile": "postDeploymentScript.sh" + }, + "resources": [ + { + "type": "Microsoft.Resources/deploymentScripts", + "apiVersion": "${azure.apiVersionForDeploymentScript}", + "tags": "[parameters('tagsByResource')['${identifier.deploymentScripts}']]", + "name": "[concat('postdeployscript-', parameters('_globalResourceNameSuffix'))]", + "kind": "AzureCLI", + "location": "[parameters('location')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[parameters('userAssignedIdentityResourceId')]": {} + } + }, + "properties": { + "forceUpdateTag": "[parameters('utcValue')]", + "azCliVersion": "2.9.1", + "timeout": "PT30M", + "cleanupPreference": "OnSuccess", + "retentionInterval": "P1D", + "primaryScriptUri": "[uri(parameters('_artifactsLocationAdminTemplate'), concat('../scripts/', variables('name_postDeploymentscriptFile'), parameters('_artifactsLocationSasToken')))]", + "environmentVariables": [ + { + "name": "MANAGED_IDENTITY_ID", + "value": "[parameters('userAssignedIdentityResourceId')]" + }, + { + "name": "RESOURCE_GROUP_NAME", + "value": "[resourceGroup().name]" + }, + { + "name": "GUID_TAG", + "value": "[parameters('const_guidTag')]" + } + ] + } + } + ], + "outputs": { + "userAssignedIdentityResource": { + "type": "string", + "value": "[parameters('userAssignedIdentityResourceId')]" + } + } +} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/postDeploymentUAMIRolesTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/postDeploymentUAMIRolesTemplate.json new file mode 100644 index 000000000..c3b66f099 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/nestedtemplates/postDeploymentUAMIRolesTemplate.json @@ -0,0 +1,109 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "metadata": { + "description": "Location for all resources." + } + }, + "_globalResourceNameSuffix": { + "type": "string", + "metadata": { + "description": "A unique suffix that was specified during the deployment of the solution template." + } + }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, + "roleAssignmentNameSeed": { + "type": "string", + "defaultValue": "[guid(subscription().id, parameters('_globalResourceNameSuffix'))]", + "metadata": { + "description": "A unique string used to generate the role assignment name. Defaults to a unique GUID based on the deployment context." + } + } + }, + "variables": { + "const_roleDefinitionIdOfContributor": "b24988ac-6180-42a0-ab88-20f7382dd24c", + "name_postDeploymentScriptUserDefinedManagedIdentity": "[concat('post-deployment-user-defined-managed-identity', parameters('_globalResourceNameSuffix'))]", + "name_postDeploymentScriptRoleAssignment": "[concat('post-deployment-user-defined-role-assignment', parameters('_globalResourceNameSuffix'))]" + }, + "resources": [ + { + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "${azure.apiVersionForIdentity}", + "tags": "[parameters('tagsByResource')['${identifier.userAssignedIdentities}']]", + "name": "[variables('name_postDeploymentScriptUserDefinedManagedIdentity')]", + "location": "[parameters('location')]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "[variables('name_postDeploymentScriptRoleAssignment')]", + "location": "[parameters('location')]", + "subscriptionId": "[subscription().subscriptionId]", + "dependsOn": [ + "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('name_postDeploymentScriptUserDefinedManagedIdentity'))]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "innerPrincipalId": { + "type": "string" + }, + "innerRoleDefinitionId": { + "type": "string" + }, + "innerRoleAssignmentNameSeed": { + "type": "string" + } + }, + "variables": { + "roleAssignmentGuid": "[guid(parameters('innerRoleAssignmentNameSeed'))]" + }, + "resources": [ + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "${azure.apiVersionForRoleAssignment}", + "name": "[variables('roleAssignmentGuid')]", + "properties": { + "roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', parameters('innerRoleDefinitionId'))]", + "principalId": "[parameters('innerPrincipalId')]", + "principalType": "ServicePrincipal" + } + } + ] + }, + "parameters": { + "innerPrincipalId": { + "value": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities',variables('name_postDeploymentScriptUserDefinedManagedIdentity'))).principalId]" + }, + "innerRoleDefinitionId": { + "value": "[variables('const_roleDefinitionIdOfContributor')]" + }, + "innerRoleAssignmentNameSeed": { + "value": "[parameters('roleAssignmentNameSeed')]" + } + } + } + } + ], + "outputs": { + "uamidForPostDeployment": { + "type": "string", + "value": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('name_postDeploymentScriptUserDefinedManagedIdentity'))]" + } + } +} \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/resources/marketing-artifacts/partner-center.html b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/resources/marketing-artifacts/partner-center.html new file mode 100644 index 000000000..ac5f8d0b8 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/resources/marketing-artifacts/partner-center.html @@ -0,0 +1,44 @@ +

    Name

    +

    Oracle WebLogic Server with Admin Server on Azure VM

    +

    Search results summary

    +

    Provisions WebLogic Server with an Admin only domain on an Azure VM.

    +

    Short description

    +

    Provisions WebLogic Server Enterprise Edition with an Admin only domain, and starts the Administration Server.

    +

    Description

    +

    Oracle WebLogic Server (WLS) is an industry-leading Java runtime powering some of the most mission-critical enterprise applications + across the globe. This solution automates most boilerplate steps to provision a single WLS Admin Server on an Azure VM. Once initial + provisioning is complete, you are completely free to customize deployments further. The solution is jointly developed by Oracle and + Microsoft.

    +

    WLS Enterprise Edition versions supported include 12.2.1.4, 14.1.1.0 and 14.1.2.0 .

    +

    The following resources are automatically provisioned by the offer.

    +
      +
    • Oracle Linux or Red Hat Enterprise Linux (RHEL) VM with public IP address
    • +
    • Single WLS Enterprise Edition Admin Server instance (ORACLE_HOME is +/u01/app/wls/install/oracle/middleware/oracle_home)
    • +
    • Oracle JDK (JAVA_HOME is /u01/app/jdk/jdk-${version})
    • +
    • In addition to drivers that come standard with WLS, most recent supported PostgreSQL and Microsoft SQL JDBC drivers (drivers stored in +/u01/app/wls/install/oracle/middleware/oracle_home/wlserver/server/lib/)
    • +
    • WebLogic Domain with default name adminDomain (domain path is /u01/domains/adminDomain/)
    • +
    • Configured data source connection (Oracle DB, Azure SQL, Azure MySQL, Azure PostgreSQL) - optional
    • +
    • Virtual network and subnet (alternatively, you can deploy to an existing virtual network)
    • +
    • Network security group
    • +
    • OS disk attached to VM
    • +
    • Azure Storage Account to store VM diagnostics
    • +
    +

    This offer is Bring-Your-Own-License. It assumes you have already procured the appropriate licenses with Oracle and are properly +licensed to run offers in Microsoft Azure.

    +

    Oracle and Microsoft also provide basic step-by-step instructions on getting started with WLS and Azure VMs without automated +provisioning.

    +

    Oracle and Microsoft provide similar solutions targeting WLS on the Azure Kubernetes Service (AKS) in addition to a WLS cluster on +Azure VMs. These options are linked in the Learn more section below.

    +

    You can reach out to the engineering team developing these offers by clicking the CONTACT ME button on +the marketplace WebLogic on Azure overview page. Program managers, architects and engineers will get in touch and can +assist you for free with your Azure migration.

    +

    Links

    + diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/aadIntegration.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/aadIntegration.sh deleted file mode 100644 index 730b5fa8f..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/aadIntegration.sh +++ /dev/null @@ -1,414 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# -#Function to output message to StdErr -function echo_stderr () -{ - echo "$@" >&2 -} - -#Function to display usage message -function usage() -{ - echo_stderr "./aadIntegration.sh <<< \"\"" -} - -function validateInput() -{ - if [[ -z "$wlsUserName" || -z "$wlsPassword" ]] - then - echo_stderr "wlsUserName or wlsPassword is required. " - exit 1 - fi - - if [ -z "$wlsDomainName" ]; - then - echo_stderr "wlsDomainName is required. " - fi - - if [ -z "$adProviderName" ]; - then - echo_stderr "adProviderName is required. " - fi - - if [ -z "$adPrincipal" ]; - then - echo_stderr "adPrincipal is required. " - fi - - if [ -z "$adPassword" ]; - then - echo_stderr "adPassword is required. " - fi - - if [ -z "$adServerHost" ]; - then - echo_stderr "adServerHost is required. " - fi - - if [ -z "$adServerPort" ]; - then - echo_stderr "adServerPort is required. " - fi - - if [ -z "$adGroupBaseDN" ]; - then - echo_stderr "adGroupBaseDN is required. " - fi - - if [ -z "$adUserBaseDN" ]; - then - echo_stderr "adUserBaseDN is required. " - fi - - if [ -z "$oracleHome" ]; - then - echo_stderr "oracleHome is required. " - fi - - if [ -z "$wlsAdminHost" ]; - then - echo_stderr "wlsAdminHost is required. " - fi - - if [ -z "$wlsAdminPort" ]; - then - echo_stderr "wlsAdminPort is required. " - fi - - if [ -z "$wlsADSSLCer" ]; - then - echo_stderr "wlsADSSLCer is required. " - fi - - if [ -z "$wlsLDAPPublicIP" ]; - then - echo_stderr "wlsLDAPPublicIP is required. " - fi - - if [ -z "$wlsDomainPath" ]; - then - echo_stderr "wlsDomainPath is required. " - fi - - if [ -z "$wlsAdminServerName" ]; - then - echo_stderr "wlsAdminServerName is required. " - fi - - if [ "${isCustomSSLEnabled,,}" != "true" ]; - then - echo_stderr "Custom SSL value is not provided. Defaulting to false" - isCustomSSLEnabled="false" - else - if [ -z "$customTrustKeyStorePassPhrase" ]; - then - echo "customTrustKeyStorePassPhrase is required " - exit 1 - fi - fi -} - -function createAADProvider_model() -{ - cat <${SCRIPT_PATH}/configure-active-directory.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') -try: - edit() - startEdit() - # Configure DefaultAuthenticator. - cd('/SecurityConfiguration/' + '${wlsDomainName}' + '/Realms/myrealm/AuthenticationProviders/DefaultAuthenticator') - cmo.setControlFlag('SUFFICIENT') - - # Configure Active Directory. - cd('/SecurityConfiguration/' + '${wlsDomainName}' + '/Realms/myrealm') - cmo.createAuthenticationProvider('${adProviderName}', 'weblogic.security.providers.authentication.ActiveDirectoryAuthenticator') - - cd('/SecurityConfiguration/' + '${wlsDomainName}' + '/Realms/myrealm/AuthenticationProviders/' + '${adProviderName}') - cmo.setControlFlag('OPTIONAL') - - cd('/SecurityConfiguration/' + '${wlsDomainName}' + '/Realms/myrealm') - set('AuthenticationProviders',jarray.array([ObjectName('Security:Name=myrealm' + '${adProviderName}'), - ObjectName('Security:Name=myrealmDefaultAuthenticator'), - ObjectName('Security:Name=myrealmDefaultIdentityAsserter')], ObjectName)) - - - cd('/SecurityConfiguration/' + '${wlsDomainName}' + '/Realms/myrealm/AuthenticationProviders/' + '${adProviderName}') - cmo.setControlFlag('SUFFICIENT') - cmo.setUserNameAttribute('${LDAP_USER_NAME}') - cmo.setUserFromNameFilter('${LDAP_USER_FROM_NAME_FILTER}') - cmo.setPrincipal('${adPrincipal}') - cmo.setHost('${adServerHost}') - set('Credential', '${adPassword}') - cmo.setGroupBaseDN('${adGroupBaseDN}') - cmo.setUserBaseDN('${adUserBaseDN}') - cmo.setPort(int('${adServerPort}')) - cmo.setSSLEnabled(true) - - # for performance tuning - cmo.setMaxGroupMembershipSearchLevel(1) - cmo.setGroupMembershipSearching('limited') - cmo.setUseTokenGroupsForGroupMembershipLookup(true) - cmo.setResultsTimeLimit(300) - cmo.setConnectionRetryLimit(5) - cmo.setConnectTimeout(120) - cmo.setCacheTTL(300) - cmo.setConnectionPoolSize(60) - cmo.setCacheSize(4000) - cmo.setGroupHierarchyCacheTTL(300) - cmo.setEnableSIDtoGroupLookupCaching(true) - - save() - activate() -except: - stopEdit('y') - sys.exit(1) - -disconnect() -sys.exit(0) -EOF -} - -function createSSL_model() -{ - cat <${SCRIPT_PATH}/configure-ssl.py -# Connect to the AdminServer. -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') -try: - edit() - startEdit() - print "set keystore to ${wlsAdminServerName}" - cd('/Servers/${wlsAdminServerName}/SSL/${wlsAdminServerName}') - cmo.setHostnameVerificationIgnored(true) - save() - activate() -except: - stopEdit('y') - sys.exit(1) - -disconnect() -sys.exit(0) -EOF -} - -function mapLDAPHostWithPublicIP() -{ - echo "map LDAP host with pubilc IP" - sudo sed -i '/${adServerHost}/d' /etc/hosts - sudo echo "${wlsLDAPPublicIP} ${adServerHost}" >> /etc/hosts -} - -function parseLDAPCertificate() -{ - echo "create key store" - cer_begin=0 - cer_size=${#wlsADSSLCer} - cer_line_len=64 - mkdir ${SCRIPT_PWD}/security - touch ${SCRIPT_PWD}/security/AzureADLDAPCerBase64String.txt - while [ ${cer_begin} -lt ${cer_size} ] - do - cer_sub=${wlsADSSLCer:$cer_begin:$cer_line_len} - echo ${cer_sub} >> ${SCRIPT_PWD}/security/AzureADLDAPCerBase64String.txt - cer_begin=$((cer_begin+64)) - done - - openssl base64 -d -in ${SCRIPT_PWD}/security/AzureADLDAPCerBase64String.txt -out ${SCRIPT_PWD}/security/AzureADTrust.cer - addsCertificate=${SCRIPT_PWD}/security/AzureADTrust.cer -} - -function importAADCertificate() -{ - # import the key to java security - . $oracleHome/oracle_common/common/bin/setWlstEnv.sh - - # For AAD failure: exception happens when importing certificate to JDK 11.0.7 - # ISSUE: https://github.com/wls-eng/arm-oraclelinux-wls/issues/109 - # JRE was removed since JDK 11. - java_version=$(java -version 2>&1 | sed -n ';s/.* version "\(.*\)\.\(.*\)\..*"/\1\2/p;') - if [ ${java_version:0:3} -ge 110 ]; - then - java_cacerts_path=${JAVA_HOME}/lib/security/cacerts - else - java_cacerts_path=${JAVA_HOME}/jre/lib/security/cacerts - fi - - # remove existing certificate. - queryAADTrust=$(${JAVA_HOME}/bin/keytool -list -keystore ${java_cacerts_path} -storepass changeit | grep "aadtrust") - if [ -n "$queryAADTrust" ]; - then - sudo ${JAVA_HOME}/bin/keytool -delete -alias aadtrust -keystore ${java_cacerts_path} -storepass changeit - fi - - sudo ${JAVA_HOME}/bin/keytool -noprompt -import -alias aadtrust -file ${addsCertificate} -keystore ${java_cacerts_path} -storepass changeit - -} - -function importAADCertificateIntoWLSCustomTrustKeyStore() -{ - if [ "${isCustomSSLEnabled,,}" == "true" ]; - then - # set java home - . $oracleHome/oracle_common/common/bin/setWlstEnv.sh - - #validate Trust keystore - sudo ${JAVA_HOME}/bin/keytool -list -v -keystore ${DOMAIN_PATH}/${wlsDomainName}/keystores/trust.keystore -storepass ${customTrustKeyStorePassPhrase} -storetype ${customTrustKeyStoreType} | grep 'Entry type:' | grep 'trustedCertEntry' - - if [[ $? != 0 ]]; then - echo "Error : Trust Keystore Validation Failed !!" - exit 1 - fi - - # For SSL enabled causes AAD failure #225 - # ISSUE: https://github.com/wls-eng/arm-oraclelinux-wls/issues/225 - - echo "Importing AAD Certificate into WLS Custom Trust Key Store: " - - sudo ${JAVA_HOME}/bin/keytool -noprompt -import -trustcacerts -keystore ${DOMAIN_PATH}/${wlsDomainName}/keystores/trust.keystore -storepass ${customTrustKeyStorePassPhrase} -alias aadtrust -file ${addsCertificate} -storetype ${customTrustKeyStoreType} - else - echo "customSSL not enabled. Not required to configure AAD for WebLogic Custom SSL" - fi -} - -function configureSSL() -{ - echo "configure ladp ssl" - sudo chown -R ${USER_ORACLE}:${GROUP_ORACLE} ${SCRIPT_PATH} - runuser -l ${USER_ORACLE} -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST ${SCRIPT_PATH}/configure-ssl.py" - - errorCode=$? - if [ $errorCode -eq 1 ] - then - echo "Exception occurs during SSL configuration, please check." - exit 1 - fi -} - -function configureAzureActiveDirectory() -{ - echo "create Azure Active Directory provider" - sudo chown -R ${USER_ORACLE}:${GROUP_ORACLE} ${SCRIPT_PATH} - runuser -l ${USER_ORACLE} -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST ${SCRIPT_PATH}/configure-active-directory.py" - - errorCode=$? - if [ $errorCode -eq 1 ] - then - echo "Exception occurs during Azure Active Directory configuration, please check." - exit 1 - fi -} - -function restartAdminServerService() -{ - echo "Restart weblogic admin server service" - sudo systemctl stop wls_admin - sudo systemctl start wls_admin -} - -#This function to check admin server status -function wait_for_admin() -{ - #check admin server status - count=1 - CHECK_URL="http://$wlsAdminURL/weblogic/ready" - status=`curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}` - echo "Check admin server status" - while [[ "$status" != "200" ]] - do - echo "." - count=$((count+1)) - if [ $count -le 30 ]; - then - sleep 1m - else - echo "Error : Maximum attempts exceeded while checking admin server status" - exit 1 - fi - status=`curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}` - if [ "$status" == "200" ]; - then - echo "WebLogic Server is running..." - break - fi - done -} - -function cleanup() -{ - echo "Cleaning up temporary files..." - rm -f -r ${SCRIPT_PATH} - rm -rf ${SCRIPT_PWD}/security/* - echo "Cleanup completed." -} - -function enableTLSv12onJDK8() -{ - if ! grep -q "${STRING_ENABLE_TLSV12}" ${wlsDomainPath}/bin/setDomainEnv.sh; then - cat <>${wlsDomainPath}/bin/setDomainEnv.sh -# Append -Djdk.tls.client.protocols to JAVA_OPTIONS in jdk8 -# Enable TLSv1.2 -\${JAVA_HOME}/bin/java -version 2>&1 | grep -e "1[.]8[.][0-9]*_" > /dev/null -javaStatus=$? - -if [[ "\${javaStatus}" = "0" && "\${JAVA_OPTIONS}" != *"${JAVA_OPTIONS_TLS_V12}"* ]]; then - JAVA_OPTIONS="\${JAVA_OPTIONS} ${JAVA_OPTIONS_TLS_V12}" - export JAVA_OPTIONS -fi -EOF -fi -} - -function createTempFolder() -{ - SCRIPT_PATH="/u01/tmp" - sudo rm -f -r ${SCRIPT_PATH} - sudo mkdir ${SCRIPT_PATH} - sudo rm -rf $SCRIPT_PATH/* -} - -#main - -read wlsUserName wlsPassword wlsDomainName adProviderName adServerHost adServerPort adPrincipal adPassword adGroupBaseDN adUserBaseDN oracleHome wlsAdminHost wlsAdminPort wlsADSSLCer wlsLDAPPublicIP wlsAdminServerName wlsDomainPath isCustomSSLEnabled customTrustKeyStorePassPhrase customTrustKeyStoreType - -isCustomSSLEnabled="${isCustomSSLEnabled,,}" - -if [ "${isCustomSSLEnabled,,}" == "true" ]; -then - customTrustKeyStorePassPhrase=$(echo "$customTrustKeyStorePassPhrase" | base64 --decode) - customTrustKeyStoreType=$(echo "$customTrustKeyStoreType" | base64 --decode) -fi - -wlsAdminURL=$wlsAdminHost:$wlsAdminPort - -LDAP_USER_NAME='sAMAccountName' -LDAP_USER_FROM_NAME_FILTER='(&(sAMAccountName=%u)(objectclass=user))' -JAVA_OPTIONS_TLS_V12="-Djdk.tls.client.protocols=TLSv1.2" -STRING_ENABLE_TLSV12="Append -Djdk.tls.client.protocols to JAVA_OPTIONS in jdk8" -SCRIPT_PWD=`pwd` -USER_ORACLE="oracle" -GROUP_ORACLE="oracle" -DOMAIN_PATH="/u01/domains" - -validateInput -createTempFolder -echo "check status of admin server" -wait_for_admin - -echo "start to configure Azure Active Directory" -enableTLSv12onJDK8 -createAADProvider_model -createSSL_model -mapLDAPHostWithPublicIP -parseLDAPCertificate -importAADCertificate -importAADCertificateIntoWLSCustomTrustKeyStore -configureSSL -configureAzureActiveDirectory -restartAdminServerService - -echo "Waiting for admin server to be available" -wait_for_admin -echo "Weblogic admin server is up and running" - -cleanup diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/datasourceConfig-mysql.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/datasourceConfig-mysql.sh new file mode 100644 index 000000000..9a1c23722 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/datasourceConfig-mysql.sh @@ -0,0 +1,186 @@ +#!/bin/bash +# Copyright (c) 2021, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +# +#read arguments from stdin +read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsShibboleth jdbcDataSourceName dsConnectionURL dsUser dsPassword dbGlobalTranPro enablePswlessConnection wlsClusterName + +if [ -z "$wlsClusterName" ]; then + wlsClusterName="cluster1" +fi + +wlsAdminURL=$wlsAdminHost:$wlsAdminPort +hostName=`hostname` + +#Function to output message to StdErr +function echo_stderr () +{ + echo "$@" >&2 +} + +#Function to display usage message +function usage() +{ + echo_stderr "./configDatasource.sh <<< \"\"" +} + +function validateInput() +{ + # parse base64 string + wlsShibboleth=$(echo "${wlsShibboleth}" | base64 -d) + jdbcDataSourceName=$(echo "${jdbcDataSourceName}" | base64 -d) + dsConnectionURL=$(echo "${dsConnectionURL}" | base64 -d) + dsPassword=$(echo "${dsPassword}" | base64 -d) + + if [ -z "$oracleHome" ]; + then + echo _stderr "Please provide oracleHome" + exit 1 + fi + + if [ -z "$wlsAdminHost" ]; + then + echo _stderr "Please provide WeblogicServer hostname" + exit 1 + fi + + if [ -z "$wlsAdminPort" ]; + then + echo _stderr "Please provide Weblogic admin port" + exit 1 + fi + + if [ -z "$wlsUserName" ]; + then + echo _stderr "Please provide Weblogic username" + exit 1 + fi + + if [ -z "$wlsShibboleth" ]; + then + echo _stderr "Please provide Weblogic password" + exit 1 + fi + + if [ -z "$jdbcDataSourceName" ]; + then + echo _stderr "Please provide JDBC datasource name to be configured" + exit 1 + fi + + if [ -z "$dsConnectionURL" ]; + then + echo _stderr "Please provide Azure database of MySQL URL in the format 'jdbc:oracle:thin:@:/'" + exit 1 + fi + + if [ -z "$dsUser" ]; + then + echo _stderr "Please provide Azure database of MySQL user name" + exit 1 + fi + + if [ -z "$dsPassword" ]; + then + echo _stderr "Please provide Azure database of MySQL password" + exit 1 + fi + + if [ -z "$dbGlobalTranPro" ]; + then + echo _stderr "Please provide Global transactions protocol" + exit 1 + fi + + if [ -z "${enablePswlessConnection}" ]; + then + echo _stderr "Please provide enablePswlessConnection to identity if enabling passwordless connection." + exit 1 + fi + + if [ -z "$wlsClusterName" ]; + then + echo _stderr "Please provide Weblogic target cluster name" + exit 1 + fi + + # reset password + if [[ "${enablePswlessConnection,,}" == "true" ]]; then + dsPassword="" + fi +} + +function createJDBCSource_model() +{ + local driverName="com.mysql.jdbc.Driver" + if [[ "${enablePswlessConnection,,}" == "true" ]]; then + driverName="com.mysql.cj.jdbc.Driver" + fi + + echo "Creating JDBC data source with name $jdbcDataSourceName" + cat <${scriptPath}/create_datasource.py +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') +edit("$hostName") +startEdit() +cd('/') +try: + cmo.createJDBCSystemResource('$jdbcDataSourceName') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName') + cmo.setName('$jdbcDataSourceName') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDataSourceParams/$jdbcDataSourceName') + set('JNDINames',jarray.array([String('$jdbcDataSourceName')], String)) + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName') + cmo.setDatasourceType('GENERIC') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDriverParams/$jdbcDataSourceName') + cmo.setUrl('$dsConnectionURL') + cmo.setDriverName('$driverName') + cmo.setPassword('$dsPassword') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCConnectionPoolParams/$jdbcDataSourceName') + cmo.setTestTableName('SQL ISVALID\r\n\r\n\r\n\r\n') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDriverParams/$jdbcDataSourceName/Properties/$jdbcDataSourceName') + cmo.createProperty('user') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDriverParams/$jdbcDataSourceName/Properties/$jdbcDataSourceName/Properties/user') + cmo.setValue('$dsUser') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDataSourceParams/$jdbcDataSourceName') + cmo.setGlobalTransactionsProtocol('${dbGlobalTranPro}') + cd('/JDBCSystemResources/$jdbcDataSourceName') + set('Targets',jarray.array([ObjectName('com.bea:Name=admin,Type=Server')], ObjectName)) + save() + resolve() + activate() +except Exception, e: + e.printStackTrace() + dumpStack() + undo('true',defaultAnswer='y') + cancelEdit('y') + destroyEditSession("$hostName",force = true) + raise("$jdbcDataSourceName configuration failed") +destroyEditSession("$hostName",force = true) +disconnect() +EOF +} + +function createTempFolder() +{ + scriptPath="/u01/tmp" + sudo rm -f -r ${scriptPath} + sudo mkdir ${scriptPath} + sudo rm -rf $scriptPath/* +} + +createTempFolder +validateInput +createJDBCSource_model + +sudo chown -R oracle:oracle ${scriptPath} +runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST ${scriptPath}/create_datasource.py" + +errorCode=$? +if [ $errorCode -eq 1 ] +then + echo "Exception occurs during DB configuration, please check." + exit 1 +fi + +echo "Cleaning up temporary files..." +rm -f -r ${scriptPath} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/datasourceConfig-oracle.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/datasourceConfig-oracle.sh index 6c7cd5a56..6e42ae9c4 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/datasourceConfig-oracle.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/datasourceConfig-oracle.sh @@ -19,6 +19,11 @@ function usage() function validateInput() { + # parse base64 string + wlsShibboleth=$(echo "${wlsShibboleth}" | base64 -d) + jdbcDataSourceName=$(echo "${jdbcDataSourceName}" | base64 -d) + dsConnectionURL=$(echo "${dsConnectionURL}" | base64 -d) + dsPassword=$(echo "${dsPassword}" | base64 -d) if [ -z "$oracleHome" ]; then @@ -44,7 +49,7 @@ function validateInput() exit 1 fi - if [ -z "$wlsPassword" ]; + if [ -z "$wlsShibboleth" ]; then echo _stderr "Please provide Weblogic password" exit 1 @@ -74,19 +79,35 @@ function validateInput() exit 1 fi + if [ -z "$dbGlobalTranPro" ]; + then + echo _stderr "Please provide Global transactions protocol" + exit 1 + fi + if [ -z "$wlsClusterName" ]; then echo _stderr "Please provide Weblogic target cluster name" exit 1 fi + if [ -z "${enablePswlessConnection}" ]; + then + echo _stderr "Please provide enablePswlessConnection to identity if enabling passwordless connection." + exit 1 + fi + + # reset password + if [[ "${enablePswlessConnection,,}" == "true" ]]; then + dsPassword="" + fi } function createJDBCSource_model() { echo "Creating JDBC data source with name $jdbcDataSourceName" cat <${scriptPath}/create_datasource.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') edit("$hostName") startEdit() cd('/') @@ -109,7 +130,7 @@ try: cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDriverParams/$jdbcDataSourceName/Properties/$jdbcDataSourceName/Properties/user') cmo.setValue('$dsUser') cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDataSourceParams/$jdbcDataSourceName') - cmo.setGlobalTransactionsProtocol('EmulateTwoPhaseCommit') + cmo.setGlobalTransactionsProtocol('${dbGlobalTranPro}') cd('/JDBCSystemResources/$jdbcDataSourceName') set('Targets',jarray.array([ObjectName('com.bea:Name=admin,Type=Server')], ObjectName)) save() @@ -138,7 +159,7 @@ function createTempFolder() #main #read arguments from stdin -read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsPassword jdbcDataSourceName dsConnectionURL dsUser dsPassword wlsClusterName +read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsShibboleth jdbcDataSourceName dsConnectionURL dsUser dsPassword dbGlobalTranPro enablePswlessConnection wlsClusterName wlsAdminURL=$wlsAdminHost:$wlsAdminPort hostName=`hostname` diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/datasourceConfig-postgresql.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/datasourceConfig-postgresql.sh index 24c98c9ec..03140c6a9 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/datasourceConfig-postgresql.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/datasourceConfig-postgresql.sh @@ -19,6 +19,11 @@ function usage() function validateInput() { + # parse base64 string + wlsShibboleth=$(echo "${wlsShibboleth}" | base64 -d) + jdbcDataSourceName=$(echo "${jdbcDataSourceName}" | base64 -d) + dsConnectionURL=$(echo "${dsConnectionURL}" | base64 -d) + dsPassword=$(echo "${dsPassword}" | base64 -d) if [ -z "$oracleHome" ]; then @@ -44,7 +49,7 @@ function validateInput() exit 1 fi - if [ -z "$wlsPassword" ]; + if [ -z "$wlsShibboleth" ]; then echo _stderr "Please provide Weblogic password" exit 1 @@ -60,12 +65,16 @@ function validateInput() then echo _stderr "Please provide PostgreSQL Database URL in the format 'jdbc:oracle:thin:@:/'" exit 1 + else + echo "dsConnectionURL=$dsConnectionURL" fi if [ -z "$dsUser" ]; then echo _stderr "Please provide PostgreSQL Database user name" exit 1 + else + echo "dsUser=$dsUser" fi if [ -z "$dsPassword" ]; @@ -74,19 +83,37 @@ function validateInput() exit 1 fi + if [ -z "$dbGlobalTranPro" ]; + then + echo _stderr "Please provide Global transactions protocol" + exit 1 + fi + if [ -z "$wlsClusterName" ]; then echo _stderr "Please provide Weblogic target cluster name" exit 1 fi + if [ -z "${enablePswlessConnection}" ]; + then + echo _stderr "Please provide enablePswlessConnection to identity if enabling passwordless connection." + exit 1 + else + echo "enablePswlessConnection=$enablePswlessConnection" + fi + + # reset password + if [[ "${enablePswlessConnection,,}" == "true" ]]; then + dsPassword="" + fi } function createJDBCSource_model() { echo "Creating JDBC data source with name $jdbcDataSourceName" cat <${scriptPath}/create_datasource.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') edit("$hostName") startEdit() cd('/') @@ -109,7 +136,7 @@ try: cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDriverParams/$jdbcDataSourceName/Properties/$jdbcDataSourceName/Properties/user') cmo.setValue('$dsUser') cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDataSourceParams/$jdbcDataSourceName') - cmo.setGlobalTransactionsProtocol('EmulateTwoPhaseCommit') + cmo.setGlobalTransactionsProtocol('${dbGlobalTranPro}') cd('/JDBCSystemResources/$jdbcDataSourceName') set('Targets',jarray.array([ObjectName('com.bea:Name=admin,Type=Server')], ObjectName)) save() @@ -135,7 +162,6 @@ function createTempFolder() sudo rm -rf $scriptPath/* } - # store arguments in a special array args=("$@") # get number of elements @@ -144,7 +170,7 @@ ELEMENTS=${#args[@]} #main #read arguments from stdin -read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsPassword jdbcDataSourceName dsConnectionURL dsUser dsPassword wlsClusterName +read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsShibboleth jdbcDataSourceName dsConnectionURL dsUser dsPassword dbGlobalTranPro enablePswlessConnection wlsClusterName wlsAdminURL=$wlsAdminHost:$wlsAdminPort hostName=`hostname` diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/datasourceConfig-sqlserver.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/datasourceConfig-sqlserver.sh index b71837fee..c754bf442 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/datasourceConfig-sqlserver.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/datasourceConfig-sqlserver.sh @@ -19,6 +19,11 @@ function usage() function validateInput() { + # parse base64 string + wlsShibboleth=$(echo "${wlsShibboleth}" | base64 -d) + jdbcDataSourceName=$(echo "${jdbcDataSourceName}" | base64 -d) + dsConnectionURL=$(echo "${dsConnectionURL}" | base64 -d) + dsPassword=$(echo "${dsPassword}" | base64 -d) if [ -z "$oracleHome" ]; then @@ -44,7 +49,7 @@ function validateInput() exit 1 fi - if [ -z "$wlsPassword" ]; + if [ -z "$wlsShibboleth" ]; then echo _stderr "Please provide Weblogic password" exit 1 @@ -74,19 +79,36 @@ function validateInput() exit 1 fi + if [ -z "$dbGlobalTranPro" ]; + then + echo _stderr "Please provide Global transactions protocol" + exit 1 + fi + if [ -z "$wlsClusterName" ]; then echo _stderr "Please provide Weblogic target cluster name" exit 1 fi + if [ -z "${enablePswlessConnection}" ]; + then + echo _stderr "Please provide enablePswlessConnection to identity if enabling passwordless connection." + exit 1 + fi + + # reset password and user + if [[ "${enablePswlessConnection,,}" == "true" ]]; then + dsPassword="" + dsUser="" + fi } function createJDBCSource_model() { echo "Creating JDBC data source with name $jdbcDataSourceName" cat <${scriptPath}/create_datasource.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') edit("$hostName") startEdit() cd('/') @@ -109,7 +131,7 @@ try: cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDriverParams/$jdbcDataSourceName/Properties/$jdbcDataSourceName/Properties/user') cmo.setValue('$dsUser') cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDataSourceParams/$jdbcDataSourceName') - cmo.setGlobalTransactionsProtocol('EmulateTwoPhaseCommit') + cmo.setGlobalTransactionsProtocol('${dbGlobalTranPro}') cd('/JDBCSystemResources/$jdbcDataSourceName') set('Targets',jarray.array([ObjectName('com.bea:Name=admin,Type=Server')], ObjectName)) save() @@ -138,7 +160,7 @@ function createTempFolder() #main #read arguments from stdin -read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsPassword jdbcDataSourceName dsConnectionURL dsUser dsPassword wlsClusterName +read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsShibboleth jdbcDataSourceName dsConnectionURL dsUser dsPassword dbGlobalTranPro enablePswlessConnection wlsClusterName wlsAdminURL=$wlsAdminHost:$wlsAdminPort hostName=`hostname` diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/elkIntegration.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/elkIntegration.sh deleted file mode 100644 index b4027a59e..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/elkIntegration.sh +++ /dev/null @@ -1,680 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. - -# Description -# This script configures ELK (Elasticsearch, Logstash and Kibana) Stack on WebLogic Server Domain. - -#Function to output message to StdErr -function echo_stderr () -{ - echo "$@" >&2 -} - -#Function to display usage message -function usage() -{ - echo_stderr "./elkIntegration.sh <<< \"\"" -} - -function validate_input() -{ - if [ -z "$oracleHome" ]; - then - echo_stderr "oracleHome is required. " - exit 1 - fi - - if [[ -z "$wlsAdminHost" || -z "$wlsAdminPort" ]] - then - echo_stderr "wlsAdminHost or wlsAdminPort is required. " - exit 1 - fi - - if [[ -z "$wlsUserName" || -z "$wlsPassword" ]] - then - echo_stderr "wlsUserName or wlsPassword is required. " - exit 1 - fi - - if [ -z "$wlsAdminServerName" ]; - then - echo_stderr "wlsAdminServerName is required. " - exit 1 - fi - - if [ -z "$elasticURI" ]; - then - echo_stderr "elasticURI is required. " - exit 1 - fi - - if [[ -z "$elasticUserName" || -z "$elasticPassword" ]] - then - echo_stderr "elasticUserName or elasticPassword is required. " - exit 1 - fi - - if [ -z "$wlsDomainName" ]; - then - echo_stderr "wlsDomainName is required. " - exit 1 - fi - - if [ -z "$wlsDomainPath" ]; - then - echo_stderr "wlsDomainPath is required. " - exit 1 - fi - - if [ -z "$logsToIntegrate" ]; - then - echo_stderr "logsToIntegrate is required. " - exit 1 - fi - - if [ -z "$logIndex" ]; - then - echo_stderr "logIndex is required. " - exit 1 - fi -} - -# Set access log with format: date time time-taken bytes c-ip s-ip c-dns s-dns cs-method cs-uri sc-status sc-comment ctx-ecid -# Redirect stdout logging enabled: true -# Redirect stderr logging enabled: true -# Stack Traces to stdout: true -function create_wls_log_model() -{ - cat <${SCRIPT_PATH}/configure-wls-log.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') -try: - edit("$hostName") - startEdit() - cd('/Servers/${wlsAdminServerName}/WebServer/${wlsAdminServerName}/WebServerLog/${wlsAdminServerName}') - cmo.setLogFileFormat('extended') - cmo.setELFFields('date time time-taken bytes c-ip s-ip c-dns s-dns cs-method cs-uri sc-status sc-comment ctx-ecid ctx-rid') - cmo.setLogTimeInGMT(true) - - cd('/Servers/${wlsAdminServerName}/Log/${wlsAdminServerName}') - cmo.setRedirectStderrToServerLogEnabled(true) - cmo.setRedirectStdoutToServerLogEnabled(true) - cmo.setStdoutLogStack(true) - - save() - resolve() - activate() -except: - stopEdit('y') - sys.exit(1) - -destroyEditSession("$hostName",force = true) -disconnect() -EOF -} - -# Remove existing Logstash -function remove_logstash() -{ - sudo systemctl status logstash - if [ $? -ne 0 ]; then - sudo systemctl stop logstash - fi - - sudo yum remove -y -v logstash - if [ $? -ne 0 ]; then - echo_stderr "Fail to remove existing Logstash." - exit 1 - fi -} - -# Install Logstash -function install_logstash() -{ - sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch - - cat < /etc/yum.repos.d/logstash.repo -[logstash-7.x] -name=Elastic repository for 7.x packages -baseurl=https://artifacts.elastic.co/packages/7.x/yum -gpgcheck=1 -gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch -enabled=1 -autorefresh=1 -type=rpm-md -EOF - sudo yum install -y -v logstash - if [ ! -d "/usr/share/logstash" ]; then - echo_stderr "Fail to install Logstash." - exit 1 - fi -} - -# Start Logstash service -function start_logstash() -{ - sudo systemctl enable logstash - sudo systemctl daemon-reload - - #Start logstash - attempt=1 - while [[ $attempt -lt 4 ]] - do - echo "Starting logstash service attempt $attempt" - sudo systemctl start logstash - attempt=`expr $attempt + 1` - sudo systemctl status logstash | grep running - if [[ $? == 0 ]]; - then - echo "logstash service started successfully" - break - fi - sleep 1m - done -} - -# Configure Logstash: -# * grok patterns -> /etc/logstash/patterns/weblogic-logstash-patterns.txt -# * conf files -> /etc/logstash/conf.d/weblogic-logs.conf -# * JAVA_HOME -> /etc/logstash/startup.options -# * create logstash start up -# Examples for patterns: -# * ACCESSDATE -# * parse date of access -# * 2020-09-01 -# * DBDATETIME -# * parse data source datetime -# * Tue Sep 01 05:05:41 UTC 2020 -# * DSIDORTIMESTAMP -# * parse data source dynamic fields: id | timestamp, one of them exists. -# * timestamp: Tue Sep 01 05:05:41 UTC 2020 -# * id: 64 -# * DSPARTITION -# * parse partition info. -# * [partition-name: DOMAIN] [partition-id: 0] -# * [partition-id: 0] [partition-name: DOMAIN] -# * DSWEBLOGICMESSAGE -# * parse data source user id or error messsage. -# * error: Java stack trace -# * user id: -# * WEBLOGICDIAGMESSAGE -# * parse domain log message. -# * e.g. Java stack trace -# * e.g. Self-tuning thread pool contains 0 running threads, 2 idle threads, and 13 standby threads -# * WEBLOGICDOMAINDATE -# * parse domain|server log datetime. -# * from wls 14: Sep 1, 2020, 5:41:51,040 AM Coordinated Universal Time -# * from wls 12: Sep 1, 2020 5:41:51,040 AM Coordinated Universal Time -# * WEBLOGICLOGPARTITION -# * parse partition info in domain log. -# * [severity-value: 64] -# * [severity-value: 64] [rid: 0] -# * [severity-value: 64] [partition-id: 0] [partition-name: DOMAIN ] -# * [severity-value: 64] [rid: 0] [partition-id: 0] [partition-name: DOMAIN ] -# * WEBLOGICSERVERLOGPARTITION -# * parse partition info in server log. -# * [severity-value: 64] -# * [severity-value: 64] [rid: 0] -# * [severity-value: 64] [partition-id: 0] [partition-name: DOMAIN ] -# * [severity-value: 64] [rid: 0] [partition-id: 0] [partition-name: DOMAIN ] -# * WEBLOGICSERVERRID -# * parse dynamic filed rid in server log. -# * [rid: 0] -# * WEBLOGICSERVERMESSAGE -# * parse field message in server log. -# * e.g. Java stack trace -# * e.g. Self-tuning thread pool contains 0 running threads, 2 idle threads, and 13 standby threads -# * WEBLOGICSTDDATE -# * parse field date in std log. -# * Aug 31, 2020 5:37:27,646 AM UTC -# * Aug 31, 2020 5:37:27 AM UTC -function configure_lostash() -{ - echo "create patterns" - rm -f -r /etc/logstash/patterns - if [ -d "/etc/logstash/patterns" ]; then - rm -f /etc/logstash/patterns/weblogic-logstash-patterns.txt - else - mkdir /etc/logstash/patterns - fi - cat </etc/logstash/patterns/weblogic-logstash-patterns.txt -ACCESSDATE ^\d{4}[./-]%{MONTHNUM}[./-]%{MONTHDAY} -DBDATETIME %{DAY} %{MONTH:db_month} %{MONTHDAY:db_day} %{HOUR:db_hour}:%{MINUTE:db_minute}:%{SECOND:db_second} %{TZ:db_tz} %{YEAR:db_year} -DSIDORTIMESTAMP (?(\b(?:[1-9][0-9]*)\b))|%{DBDATETIME:ds_timestamp} -DSPARTITION (?:\[partition-id: %{INT:ds_partitionId}\] \[partition-name: %{DATA:ds_partitionName}\]\s)|(?:\[partition-name: %{DATA:ds_partitionName}\] \[partition-id: %{INT:ds_partitionId}\]\s) -DSWEBLOGICMESSAGE (?(.|\r|\n)*)|%{GREEDYDATA:ds_user} -JAVAPACKAGE ([a-zA-Z_$][a-zA-Z\d_$]*\.)*[a-zA-Z_$][a-zA-Z\d_$]* -WEBLOGICDIAGMESSAGE (?(.|\r|\n)*)|%{GREEDYDATA:diag_message} -WEBLOGICDOMAINDATE %{MONTH:tmp_month} %{MONTHDAY:tmp_day}, %{YEAR:tmp_year},? %{HOUR:tmp_hour}:%{MINUTE:tmp_min}:%{SECOND:tmp_second},(?([0-9]{3})) (?(AM|PM)) -WEBLOGICLOGPARTITION (?:\s\[rid: %{DATA:diag_rid}\] \[partition-id: %{INT:diag_partitionId}\] \[partition-name: %{DATA:diag_partitionName}\]\s)|(?:\s\[partition-id: %{INT:diag_partitionId}\] \[partition-name: %{DATA:diag_partitionName}\]\s)|(?:\s\[rid: %{DATA:diag_rid}\]\s)|(\s) -WEBLOGICSERVERLOGPARTITION (?:\s\[rid: %{DATA:log_rid}\] \[partition-id: %{INT:log_partitionId}\] \[partition-name: %{DATA:log_partitionName}\]\s)|(?:\s\[partition-id: %{INT:log_partitionId}\] \[partition-name: %{DATA:log_partitionName}\]\s)|(?:\s\[rid: %{DATA:log_rid}\]\s)|(\s) -WEBLOGICSERVERRID (?:\s\[rid: %{WORDNOSPACES:log_rid}\]\s)|(\s) -WEBLOGICSERVERMESSAGE (?(.|\r|\n)*)|%{GREEDYDATA:log_message} -WEBLOGICSTDDATE %{MONTH} %{MONTHDAY}, %{YEAR} %{HOUR}:%{MINUTE}:%{SECOND} (AM|PM) -WORDNOSPACES [^ ]* -WORDNOBRACKET [^\]]* -EOF - - wlsLogPath="${wlsDomainPath}/servers/${wlsAdminServerName}/logs" - privateIP=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/') - - rm -f /etc/logstash/conf.d/weblogic-logs.conf - cat </etc/logstash/conf.d/weblogic-logs.conf -input { -EOF - - if [[ -n `echo ${logsToIntegrate} | grep "HTTPAccessLog"` ]]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { - path => "${wlsLogPath}/access.log" - start_position => beginning - } -EOF - fi - - if [[ -n `echo ${logsToIntegrate} | grep "ServerLog"` ]]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { - path => "${wlsLogPath}/${wlsAdminServerName}.log" - codec => multiline { - pattern => "^####" - negate => true - what => "previous" - } - start_position => beginning - } -EOF - fi - - if [[ -n `echo ${logsToIntegrate} | grep "DomainLog"` ]]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { - path => "${wlsLogPath}/${wlsDomainName}.log" - codec => multiline { - pattern => "^####" - negate => true - what => "previous" - } - start_position => beginning - } -EOF - fi - - if [[ -n `echo ${logsToIntegrate} | grep "DataSourceLog"` ]]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { - path => "${wlsLogPath}/datasource.log" - codec => multiline { - pattern => "^####" - negate => true - what => "previous" - } - start_position => beginning - } -EOF - fi - - if [[ -n `echo ${logsToIntegrate} | grep "StandardErrorAndOutput"` ]]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { - path => "${wlsLogPath}/${wlsAdminServerName}.out" - codec => multiline { - pattern => "^<" - negate => true - what => "previous" - } - start_position => beginning - } -EOF - fi - - cat <>/etc/logstash/conf.d/weblogic-logs.conf -} -filter { - grok { - match => {"path" => "%{GREEDYDATA}/%{GREEDYDATA:type}"} - } - mutate { - add_field => { "internal_ip" => "${privateIP}" } - } - - if [type] == "${wlsAdminServerName}.log" { - mutate { replace => { type => "weblogic_server_log" } } - # match rid - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "####<%{WEBLOGICDOMAINDATE}%{SPACE}%{GREEDYDATA:log_timezone}>%{SPACE}<%{LOGLEVEL:log_severity}>%{SPACE}<%{GREEDYDATA:log_subSystem}>%{SPACE}<%{HOSTNAME:log_machine}>%{SPACE}<%{DATA:log_server}>%{SPACE}<%{DATA:log_thread}>%{SPACE}<%{DATA:log_userId}>%{SPACE}<%{DATA:log_transactionId}>%{SPACE}<%{DATA:log_contextId}>%{SPACE}<%{NUMBER:log_timestamp}>%{SPACE}<\[severity-value: %{INT:log_severityValue}\]%{WEBLOGICSERVERLOGPARTITION}>%{SPACE}<%{DATA:log_massageId}>%{SPACE}<%{WEBLOGICSERVERMESSAGE}>" ] - } - - mutate { - replace => ['log_date', '%{tmp_month} %{tmp_day}, %{tmp_year} %{tmp_hour}:%{tmp_min}:%{tmp_second},%{tmp_sss} %{tmp_aa}'] - } - - translate { - field => 'log_timezone' - destination => 'log_timezone' - fallback => '%{log_timezone}' - override => "true" - dictionary => [ - 'Coordinated Universal Time', 'UTC' - ] - } - - date { - match => [ "log_date", "MMM dd, YYYY KK:mm:ss,SSS aa", "MMM d, YYYY KK:mm:ss,SSS aa"] - timezone => "%{log_timezone}" - target => "log_date" - } - mutate { - remove_field => [ 'log_timezone', 'tmp_month', 'tmp_day', 'tmp_year', 'tmp_hour', 'tmp_min', 'tmp_second', 'tmp_sss', 'tmp_aa'] - } - } - else if [type] == "access.log" { - # drop message starting with # - if [message] =~ /^#/ { - drop {} - } - mutate { replace => { type => "weblogic_access_log" } } - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "%{ACCESSDATE:acc_date}\s+%{TIME:acc_time}\s+%{NUMBER:time_taken}\s+%{NUMBER:bytes:int}\s+%{IP:c_ip}\s+%{HOSTPORT:s_ip}\s+%{IPORHOST:c_dns}\s+%{IPORHOST:s_dns}\s+%{WORD:cs_method}\s+%{URIPATHPARAM:cs_uri}\s+%{NUMBER:sc_status}\s+%{QUOTEDSTRING:sc-comment}\s+%{WORDNOSPACES:ctx-ecid}\s+%{WORDNOSPACES:ctx-rid}" ] - } - mutate { - replace => ['acc_timestamp', '%{acc_date} %{acc_time}'] - } - date { - match => [ "acc_timestamp" , "yyyy-MM-dd HH:mm:ss" ] - timezone => "UTC" - target => "acc_timestamp" - } - mutate { - remove_field => [ 'acc_date', 'acc_time'] - } - } - else if [type] == "${wlsDomainName}.log" { - mutate { replace => { type => "weblogic_domain_log" } } - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "####<%{WEBLOGICDOMAINDATE}%{SPACE}%{GREEDYDATA:diag_timezone}>%{SPACE}<%{LOGLEVEL:diag_severity}>%{SPACE}<%{GREEDYDATA:diag_subSystem}>%{SPACE}<%{HOSTNAME:diag_machine}>%{SPACE}<%{HOSTNAME:diag_server}>%{SPACE}<%{DATA:diag_thread}>%{SPACE}<%{WORDNOBRACKET:diag_userId}>%{SPACE}<%{DATA:diag_transactionId}>%{SPACE}<%{WORDNOSPACES:diag_contextId}>%{SPACE}<%{NUMBER:diag_timestamp}>%{SPACE}<\[severity-value: %{INT:diag_severityValue}\]%{WEBLOGICLOGPARTITION}>%{SPACE}<%{DATA:diag_massageId}>%{SPACE}<%{WEBLOGICDIAGMESSAGE}>" ] - } - - mutate { - replace => ['diag_date', '%{tmp_month} %{tmp_day}, %{tmp_year} %{tmp_hour}:%{tmp_min}:%{tmp_second},%{tmp_sss} %{tmp_aa}'] - } - - translate { - field => 'diag_timezone' - destination => 'diag_timezone' - fallback => '%{diag_timezone}' - override => "true" - dictionary => [ - 'Coordinated Universal Time', 'UTC' - ] - } - - date { - match => [ "diag_date", "MMM dd, YYYY KK:mm:ss,SSS aa", "MMM d, YYYY KK:mm:ss,SSS aa"] - timezone => "%{diag_timezone}" - target => "diag_date" - } - mutate { - remove_field => [ 'diag_timezone', 'tmp_month', 'tmp_day', 'tmp_year', 'tmp_hour', 'tmp_min', 'tmp_second', 'tmp_sss', 'tmp_aa'] - } - } - else if [type] == "datasource.log" { - mutate { replace => { type => "weblogic_datasource_log" } } - # with timestamp - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "####<%{WORDNOSPACES:ds_dataSource}>%{SPACE}<%{WORDNOSPACES:ds_profileType}>%{SPACE}<%{DSIDORTIMESTAMP}>%{SPACE}<%{DSWEBLOGICMESSAGE}>%{SPACE}<%{DATA:ds_info}>%{SPACE}<%{DSPARTITION}>" ] - } - - if ([db_month]) { - # DBDATETIME %{DAY} %{MONTH:db_month} %{MONTHDAY:db_day} %{HOUR:db_hour}:%{MINUTE:db_minute}:%{SECOND:db_second} %{TZ:db_tz} %{YEAR:db_year} - mutate { - replace => ["ds_timestamp", "%{db_month} %{db_day}, %{db_year} %{db_hour}:%{db_minute}:%{db_second}"] - } - - date { - match => [ "ds_timestamp", "MMM dd, YYYY HH:mm:ss", "MMM d, YYYY HH:mm:ss"] - timezone => "%{db_tz}" - target => "ds_timestamp" - } - mutate { - remove_field => [ 'db_month','db_day','db_year','db_hour','db_minute','db_second','db_tz'] - } - } - } - else if [type] == "${wlsAdminServerName}.out" { - mutate { replace => { type => "weblogic_std_log" } } - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "<%{WEBLOGICSTDDATE:out_timestamp}%{SPACE}%{TZ:out_timezone}>%{SPACE}<%{LOGLEVEL:out_level}>%{SPACE}<%{GREEDYDATA:out_subsystem}>%{SPACE}<%{DATA:out_messageId}>%{SPACE}<(?(.|\r|\n)*)|%{GREEDYDATA:out_message}>"] - } - - # CEST id does not exist in JODA-TIME, changed to CET - translate { - field => 'out_timezone' - destination => 'out_timezone' - fallback => '%{out_timezone}' - override => "true" - dictionary => [ - 'CEST', 'CET' - ] - } - date { - match => [ "out_timestamp", "MMM dd, YYYY KK:mm:ss aa", "MMM d, YYYY KK:mm:ss aa", "MMM dd, YYYY KK:mm:ss,SSS aa", "MMM d, YYYY KK:mm:ss,SSS aa"] - timezone => "%{out_timezone}" - target => "out_timestamp" - } - mutate { - remove_field => [ 'out_timezone'] - } - } -} -output { - elasticsearch { - hosts => "${elasticURI}" - user => "${elasticUserName}" - password => "${elasticPassword}" - index => "${logIndex}" - } -} -EOF - - # Add JAVA_HOME to startup.options - cp /etc/logstash/startup.options /etc/logstash/startup.options.elksave - sed -i -e "/JAVACMD/a\\JAVA_HOME=${JAVA_HOME}" /etc/logstash/startup.options - # Start logstash with oracle user - sed -i -e "s:LS_USER=.*:LS_USER=${userOracle}:g" /etc/logstash/startup.options - sed -i -e "s:LS_GROUP=.*:LS_GROUP=${groupOracle}:g" /etc/logstash/startup.options - - # For Java 11 - # ISSUE: https://github.com/elastic/logstash/issues/10496 - java_version=$(java -version 2>&1 | sed -n ';s/.* version "\(.*\)\.\(.*\)\..*"/\1\2/p;') - if [ ${java_version:0:3} -ge 110 ]; - then - cp /etc/logstash/jvm.options /etc/logstash/jvm.options.elksave - cat <>/etc/logstash/jvm.options ---add-opens java.base/sun.nio.ch=org.jruby.dist ---add-opens java.base/java.io=org.jruby.dist -EOF - fi - - # create start up for logstash - /usr/share/logstash/bin/system-install /etc/logstash/startup.options - if [ $? -ne 0 ]; - then - echo_stderr "Failed to set up logstash service." - exit 1 - fi - - sudo chown -R ${userOracle}:${groupOracle} /var/lib/logstash - sudo chown -R ${userOracle}:${groupOracle} /etc/logstash -} - -function configure_wls_log() -{ - echo "Configure WebLogic Log" - sudo chown -R ${userOracle}:${groupOracle} ${SCRIPT_PATH} - runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST ${SCRIPT_PATH}/configure-wls-log.py" - - errorCode=$? - if [ $errorCode -eq 1 ] - then - echo "Exception occurs during ELK configuration, please check." - exit 1 - fi -} - -function setup_javahome() -{ - . $oracleHome/oracle_common/common/bin/setWlstEnv.sh -} - -function restart_admin_service() -{ - echo "Restart weblogic admin server" - echo "Stop admin server" - shutdown_admin - sudo systemctl start wls_admin - echo "Waiting for admin server to be available" - wait_for_admin - echo "Weblogic admin server is up and running" -} - -#This function to check admin server status -function wait_for_admin() -{ - #check admin server status - count=1 - CHECK_URL="http://$wlsAdminURL/weblogic/ready" - status=`curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}` - echo "Check admin server status" - while [[ "$status" != "200" ]] - do - echo "." - count=$((count+1)) - if [ $count -le 30 ]; - then - sleep 1m - else - echo "Error : Maximum attempts exceeded while checking admin server status" - exit 1 - fi - status=`curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}` - if [ "$status" == "200" ]; - then - echo "WebLogic Server is running..." - break - fi - done -} - -# shutdown admin server -function shutdown_admin() { - #check admin server status - count=1 - CHECK_URL="http://$wlsAdminURL/weblogic/ready" - status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) - echo "Check admin server status" - while [[ "$status" == "200" ]]; do - echo "." - count=$((count + 1)) - sudo systemctl stop wls_admin - if [ $count -le 30 ]; then - sleep 1m - else - echo "Error : Maximum attempts exceeded while stopping admin server" - exit 1 - fi - status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) - if [ -z ${status} ]; then - echo "WebLogic Server is stop..." - break - fi - done -} - -function cleanup() -{ - echo "Cleaning up temporary files..." - rm -f -r ${SCRIPT_PATH} - echo "Cleanup completed." -} - -function create_temp_folder() -{ - SCRIPT_PATH="/u01/tmp" - sudo rm -f -r ${SCRIPT_PATH} - sudo mkdir ${SCRIPT_PATH} - sudo rm -rf $SCRIPT_PATH/* -} - -function validate_elastic_server() -{ - timestamp=$(date +%s) - testIndex="${logIndex}-validate-elk-server-from-admin-server-${timestamp}" - output=$(curl -XPUT --user ${elasticUserName}:${elasticPassword} ${elasticURI}/${testIndex}) - if [[ $? -eq 1 || -z `echo $output | grep "\"acknowledged\":true"` ]];then - echo $output - exit 1 - fi - - count=1 - status404="\"status\":404" - while [[ -n ${status404} ]]; do - echo "." - count=$((count + 1)) - # remove the test index - echo "Removing test index..." - curl -XDELETE --user ${elasticUserName}:${elasticPassword} ${elasticURI}/${testIndex} - echo "Checking if test index is removed." - status404=$(curl -XGET --user ${elasticUserName}:${elasticPassword} ${elasticURI}/${testIndex} | grep "\"status\":404") - echo ${status404} - if [[ -n ${status404} ]]; then - echo "Test index is removed..." - break - fi - - if [ $count -le 30 ]; then - sleep 1m - else - echo "Error : Maximum attempts exceeded while removing test index from elastic server" - exit 1 - fi - done -} - - -#main -SCRIPT_PWD=`pwd` - -#read arguments from stdin -read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsPassword wlsAdminServerName elasticURI elasticUserName elasticPassword wlsDomainName wlsDomainPath logsToIntegrate logIndex - -hostName=`hostname` -wlsAdminURL=$wlsAdminHost:$wlsAdminPort -userOracle="oracle" -groupOracle="oracle" - - -create_temp_folder -validate_input -validate_elastic_server - -echo "start to configure ELK" -setup_javahome -create_wls_log_model -remove_logstash -install_logstash -configure_lostash -start_logstash -configure_wls_log -restart_admin_service - -echo "Waiting for admin server to be available" -wait_for_admin -echo "Weblogic admin server is up and running" - -cleanup \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/installJdbcDrivers.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/installJdbcDrivers.sh new file mode 100644 index 000000000..0a2166503 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/installJdbcDrivers.sh @@ -0,0 +1,253 @@ +# Copyright (c) 2021, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +# Description +# This script is to install jdbc libraries at WebLogic cluster domain. + +# /bin/bash + +#Function to output message to StdErr +function echo_stderr() { + echo "$@" >&2 +} + +#Function to display usage message +function usage() { + echo_stderr "./installJdbcDrivers.sh <<< \"\"" +} + +function validate_input() { + + # parse base64 string + wlsShibboleth=$(echo "${wlsShibboleth}" | base64 -d) + + if [ -z "$oracleHome" ]; then + echo _stderr "Please provide oracleHome" + exit 1 + fi + + if [ -z "$domainPath" ]; then + echo _stderr "Please provide domainPath" + exit 1 + fi + + if [ -z "$wlsServerName" ]; then + echo _stderr "Please provide wlsServerName" + exit 1 + fi + + if [ -z "$wlsAdminHost" ]; then + echo _stderr "Please provide wlsAdminHost" + exit 1 + fi + + if [ -z "$wlsAdminPort" ]; then + echo _stderr "Please provide wlsAdminPort" + exit 1 + fi + + if [ -z "$wlsUserName" ]; then + echo _stderr "Please provide wlsUserName" + exit 1 + fi + + if [ -z "$wlsShibboleth" ]; then + echo _stderr "Please provide wlsShibboleth" + exit 1 + fi + + if [ -z "$databaseType" ]; then + echo _stderr "Please provide databaseType" + exit 1 + fi + + if [ -z "$enablePswlessConnection" ]; then + echo _stderr "Please provide enablePswlessConnection" + exit 1 + fi +} + +function install_maven() { + sudo yum install maven -y +} + +function uninstall_maven() { + sudo yum remove maven -y +} + +function install_azure_identity_extension() { + local myPomFile=pom.xml + curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -fksL "${gitUrl4AzureIdentityExtensionPomFile}" -o ${myPomFile} + if [ $? != 0 ]; then + echo_stderr "Failed to download ${gitUrl4AzureIdentityExtensionPomFile}." + fi + + echo "download dependencies" + mvn dependency:copy-dependencies -f ${myPomFile} + if [ $? -eq 0 ]; then + ls -l target/dependency/ + + domainBase=$(dirname $domainPath) + + # check if azure identity extension has been installed, if so, remove old version + if [ -d "${domainBase}/azure-libraries/identity" ]; then + sudo rm ${domainBase}/azure-libraries/identity -f -r + sudo rm ${domainBase}/azure-libraries/jackson -f -r + fi + + sudo mkdir -p ${domainBase}/azure-libraries/identity + sudo mkdir -p ${domainBase}/azure-libraries/jackson + # fix JARs conflict issue, put jackson libraries to PRE_CLASSPATH to upgrade the existing libs. + sudo mv target/dependency/jackson-annotations-*.jar ${domainBase}/azure-libraries/jackson + sudo mv target/dependency/jackson-core-*.jar ${domainBase}/azure-libraries/jackson + sudo mv target/dependency/jackson-databind-*.jar ${domainBase}/azure-libraries/jackson + sudo mv target/dependency/jackson-datatype-*.jar ${domainBase}/azure-libraries/jackson + # Those jars will be appended to CLASSPATH + sudo mv target/dependency/*.jar ${domainBase}/azure-libraries/identity + sudo chown -R oracle:oracle ${domainBase}/azure-libraries + else + echo "Failed to download dependencies for azure-identity-extension" + exit 1 + fi + + rm ${myPomFile} -f + rm target -f -r + if ! grep -q "${domainBase}/azure-libraries/identity/" "${domainPath}/bin/setDomainEnv.sh"; then + sed -i 's;^export DOMAIN_HOME;&\nCLASSPATH="'${domainBase}'/azure-libraries/identity/*:${CLASSPATH}";' ${domainPath}/bin/setDomainEnv.sh + fi + + if ! grep -q "${domainBase}/azure-libraries/jackson/" "${domainPath}/bin/setDomainEnv.sh"; then + sed -i 's;^export DOMAIN_HOME;&\nPRE_CLASSPATH="'${domainBase}'/azure-libraries/jackson/*:${PRE_CLASSPATH}";' ${domainPath}/bin/setDomainEnv.sh + fi +} + +function upgrade_mysql_driver() { + local mysqlPomFile=mysql-pom.xml + curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -fksL "${gitUrl4MySQLDriverPomFile}" -o ${mysqlPomFile} + if [ $? != 0 ]; then + echo_stderr "Failed to download ${gitUrl4MySQLDriverPomFile}." + fi + + echo "download dependencies" + mvn dependency:copy-dependencies -f ${mysqlPomFile} + if [ $? -eq 0 ]; then + ls -l target/dependency/ + + local domainBase=$(dirname $domainPath) + local preClassLibsFolderName=preclasspath-libraries + + # check if the driver has been upgraded, if so, remove old driver + if [ -e ${domainBase}/${preClassLibsFolderName}/mysql-connector-*.jar ]; then + sudo rm ${domainBase}/${preClassLibsFolderName} -f -r + fi + + sudo mkdir ${domainBase}/${preClassLibsFolderName} + sudo mv target/dependency/mysql-connector-*.jar ${domainBase}/${preClassLibsFolderName}/ + sudo chown -R oracle:oracle ${domainBase}/${preClassLibsFolderName} + else + echo "Failed to download mysql driver." + exit 1 + fi + + rm ${mysqlPomFile} -f + rm target -f -r + + if ! grep -q "${domainBase}/preclasspath-libraries/" "${domainPath}/bin/setDomainEnv.sh"; then + sed -i 's;^export DOMAIN_HOME;&\nPRE_CLASSPATH="'${domainBase}'/preclasspath-libraries/*:${PRE_CLASSPATH}";' ${domainPath}/bin/setDomainEnv.sh + fi +} + +#This function to wait for admin server +function wait_for_admin() { + #wait for admin to start + count=1 + CHECK_URL="http://$wlsAdminURL/weblogic/ready" + status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) + echo "Waiting for admin server to start" + while [[ "$status" != "200" ]]; do + echo "." + count=$((count + 1)) + if [ $count -le 30 ]; then + sleep 1m + else + echo "Error : Maximum attempts exceeded while starting admin server" + exit 1 + fi + status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) + if [ "$status" == "200" ]; then + echo "Admin Server started succesfully..." + break + fi + done +} + +function restart_admin_service() { + echo "Restart weblogic admin server service" + sudo systemctl stop wls_admin + sudo systemctl start wls_admin + wait_for_admin +} + +function restart_managed_servers() { + echo "Restart managed servers" + cat <${SCRIPT_PWD}/restart-managedServer.py +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') +servers=cmo.getServers() +domainRuntime() +print "Restart the servers which are in RUNNING status" +for server in servers: + bean="/ServerLifeCycleRuntimes/"+server.getName() + serverbean=getMBean(bean) + if (serverbean.getState() in ("RUNNING")) and (server.getName() == '${wlsServerName}'): + try: + print "Stop the Server ",server.getName() + shutdown(server.getName(),server.getType(),ignoreSessions='true',force='true') + print "Start the Server ",server.getName() + start(server.getName(),server.getType()) + break + except: + print "Failed restarting managed server ", server.getName() + dumpStack() +serverConfig() +disconnect() +EOF + . $oracleHome/oracle_common/common/bin/setWlstEnv.sh + java $WLST_ARGS weblogic.WLST ${SCRIPT_PWD}/restart-managedServer.py + + if [[ $? != 0 ]]; then + echo "Error : Fail to restart managed server to configuration external libraries." + exit 1 + fi +} + +#read arguments from stdin +read oracleHome domainPath wlsServerName wlsAdminHost wlsAdminPort wlsUserName wlsShibboleth databaseType enablePswlessConnection + +export curlMaxTime=120 # seconds +export gitUrl4AzureIdentityExtensionPomFile="https://raw.githubusercontent.com/oracle/weblogic-azure/main/weblogic-azure-aks/src/main/resources/azure-identity-extensions.xml" +export gitUrl4MySQLDriverPomFile="https://raw.githubusercontent.com/oracle/weblogic-azure/main/weblogic-azure-aks/src/main/resources/mysql-connector-java.xml" +export retryMaxAttempt=5 # retry attempt for curl command + + +export wlsAdminURL=$wlsAdminHost:$wlsAdminPort + +validate_input + +install_maven + +if [ $databaseType == "mysql" ]; then + upgrade_mysql_driver +fi + +if [ "${enablePswlessConnection,,}" == "true" ]; then + if [[ $databaseType == "mysql" || $databaseType == "postgresql" ]]; then + install_azure_identity_extension + fi +fi + +uninstall_maven + +if [ $wlsServerName == "admin" ]; then + restart_admin_service +else + restart_managed_servers +fi diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/postDeploymentScript.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/postDeploymentScript.sh new file mode 100644 index 000000000..cc3790ae2 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/postDeploymentScript.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# Copyright (c) 2021, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +#Function to output message to StdErr +function echo_stderr () +{ + echo "$@" >&2 +} + +#Function to display usage message +function usage() +{ + echo_stderr "./postDeploymentScript.sh " +} + + + +echo "Executing post Deployment script" + +# Get all public ips assigned to the network interface in a given resource group, and follow the below steps +# 1) Get the resource (public IP) tagged with supplied resource tag +# 2) Remove the public IP from netwrok interface +# 3) Finally delete all public IPs + +PUBLIC_IPS="$(az network public-ip list --resource-group ${RESOURCE_GROUP_NAME} --query "[?tags && contains(keys(tags), '${GUID_TAG}')].id" -o tsv)" +if [ -n "${PUBLIC_IPS}" ]; then + echo "Found public IPs to remove: ${PUBLIC_IPS}" + for PUBLIC_IP in ${PUBLIC_IPS}; do + IP_CONFIG_ID=$(az network public-ip show --ids "${PUBLIC_IP}" --query "ipConfiguration.id" -o tsv) + if [ -n "${IP_CONFIG_ID}" ]; then + echo "Found IP configuration: ${IP_CONFIG_ID}" + # Using IP configuration id extract Network interface name and IP config name + NIC_NAME=$(echo "${IP_CONFIG_ID}" | sed 's|.*/networkInterfaces/\([^/]*\)/.*|\1|') + IP_CONFIG_NAME=$(echo "${IP_CONFIG_ID}" | sed 's|.*/ipConfigurations/\([^/]*\).*|\1|') + echo "Removing public IP from NIC: ${NIC_NAME}, IP config: ${IP_CONFIG_NAME}" + az network nic ip-config update -g "${RESOURCE_GROUP_NAME}" --nic-name "${NIC_NAME}" -n "${IP_CONFIG_NAME}" --remove publicIPAddress + fi + done + echo "Deleting public IPs: ${PUBLIC_IPS}" + az network public-ip delete --ids ${PUBLIC_IPS} +else + echo "No public IPs found with tag ${GUID_TAG}" +fi +echo "Deleting $MANAGED_IDENTITY_ID " +az identity delete --ids $MANAGED_IDENTITY_ID \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/setupAdminDomain.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/setupAdminDomain.sh index 8d6e6a51d..6903c1a5c 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/setupAdminDomain.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/setupAdminDomain.sh @@ -2,9 +2,6 @@ # Copyright (c) 2021, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# Description -# This script configures ELK (Elasticsearch, Logstash and Kibana) Stack on WebLogic Server Domain. - #Function to output message to StdErr function echo_stderr () { @@ -69,12 +66,63 @@ function cleanup() echo "Cleaning up temporary files..." rm -rf $DOMAIN_PATH/admin-domain.yaml - rm -rf $DOMAIN_PATH/deploy-app.yaml - rm -rf $DOMAIN_PATH/shoppingcart.zip + rm -rf $DOMAIN_PATH/*.py + rm -rf ${CUSTOM_HOSTNAME_VERIFIER_HOME} echo "Cleanup completed." } +# This function verifies whether certificate is valid and not expired +function verifyCertValidity() +{ + KEYSTORE=$1 + PASSWORD=$2 + CURRENT_DATE=$3 + MIN_CERT_VALIDITY=$4 + KEY_STORE_TYPE=$5 + VALIDITY=$(($CURRENT_DATE + ($MIN_CERT_VALIDITY*24*60*60))) + + echo "Verifying $KEYSTORE is valid at least $MIN_CERT_VALIDITY day from the deployment time" + + if [ $VALIDITY -le $CURRENT_DATE ]; + then + echo_stderr "Error : Invalid minimum validity days supplied" + exit 1 + fi + + # Check whether KEYSTORE supplied can be opened for reading + # Redirecting as no need to display the contents + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $KEYSTORE -storepass $PASSWORD -storetype $KEY_STORE_TYPE > /dev/null 2>&1" + if [ $? != 0 ]; + then + echo_stderr "Error opening the keystore : $KEYSTORE" + exit 1 + fi + + aliasList=`runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $KEYSTORE -storepass $PASSWORD -storetype $KEY_STORE_TYPE | grep Alias" |awk '{print $3}'` + if [[ -z $aliasList ]]; + then + echo_stderr "Error : No alias found in supplied certificate $KEYSTORE" + exit 1 + fi + + for alias in $aliasList + do + VALIDITY_PERIOD=`runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $KEYSTORE -storepass $PASSWORD -storetype $KEY_STORE_TYPE -alias $alias | grep Valid"` + echo "$KEYSTORE is \"$VALIDITY_PERIOD\"" + CERT_UNTIL_DATE=`echo $VALIDITY_PERIOD | awk -F'until:|\r' '{print $2}'` + CERT_UNTIL_SECONDS=`date -d "$CERT_UNTIL_DATE" +%s` + VALIDITY_REMIANS_SECONDS=`expr $CERT_UNTIL_SECONDS - $VALIDITY` + if [[ $VALIDITY_REMIANS_SECONDS -le 0 ]]; + then + echo_stderr "$KEYSTORE is \"$VALIDITY_PERIOD\"" + echo_stderr "Error : Supplied certificate $KEYSTORE is either expired or expiring soon within $MIN_CERT_VALIDITY day" + exit 1 + fi + done + echo "$KEYSTORE validation is successful" +} + #Creates weblogic deployment model for admin domain function create_admin_model() { @@ -86,7 +134,7 @@ function create_admin_model() cat <$DOMAIN_PATH/admin-domain.yaml domainInfo: AdminUserName: "$wlsUserName" - AdminPassword: "$wlsPassword" + AdminPassword: "$wlsShibboleth" ServerStartMode: prod topology: Name: "$wlsDomainName" @@ -117,16 +165,18 @@ EOF ServerPrivateKeyPassPhraseEncrypted: "$serverPrivateKeyPassPhrase" ListenPort: $wlsSSLAdminPort Enabled: true + ServerStart: + Arguments: '${SERVER_STARTUP_ARGS}' WebServer: - FrontendHost: '${adminPublicHostName}' - FrontendHTTPSPort: $wlsSSLAdminPort - FrontendHTTPPort: $wlsAdminPort + FrontendHost: '${adminPublicHostName}' + FrontendHTTPSPort: $wlsSSLAdminPort + FrontendHTTPPort: $wlsAdminPort EOF else cat <>$DOMAIN_PATH/admin-domain.yaml domainInfo: AdminUserName: "$wlsUserName" - AdminPassword: "$wlsPassword" + AdminPassword: "$wlsShibboleth" ServerStartMode: prod topology: Name: "$wlsDomainName" @@ -145,31 +195,31 @@ topology: SSL: ListenPort: $wlsSSLAdminPort Enabled: true + ServerStart: + Arguments: '${SERVER_STARTUP_ARGS}' WebServer: - FrontendHost: '${adminPublicHostName}' - FrontendHTTPSPort: $wlsSSLAdminPort - FrontendHTTPPort: $wlsAdminPort + FrontendHost: '${adminPublicHostName}' + FrontendHTTPSPort: $wlsSSLAdminPort + FrontendHTTPPort: $wlsAdminPort EOF fi -} -# This function to create model for sample application deployment -function create_app_deploy_model() -{ +#check if remoteanonymous attributes are supported in current WLS version +#if supported, disable them by setting the attributes to false - echo "Creating deploying applicaton model" - cat <$DOMAIN_PATH/deploy-app.yaml -domainInfo: - AdminUserName: "$wlsUserName" - AdminPassword: "$wlsPassword" - ServerStartMode: prod -appDeployments: - Application: - shoppingcart : - SourcePath: $DOMAIN_PATH/shoppingcart.war - Target: admin - ModuleType: war +hasRemoteAnonymousAttribs="$(containsRemoteAnonymousT3RMIIAttribs)" +echo "hasRemoteAnonymousAttribs: ${hasRemoteAnonymousAttribs}" + +if [ "${hasRemoteAnonymousAttribs}" == "true" ]; +then +echo "adding settings to disable remote anonymous t3/rmi disabled under domain security configuration" +cat <>$DOMAIN_PATH/admin-domain.yaml + SecurityConfiguration: + RemoteAnonymousRmiiiopEnabled: false + RemoteAnonymousRmit3Enabled: false EOF +fi + } #Function to create Admin Only Domain @@ -204,7 +254,7 @@ echo "Creating admin server boot properties" #Create the boot.properties directory mkdir -p "$DOMAIN_PATH/$wlsDomainName/servers/admin/security" echo "username=$wlsUserName" > "$DOMAIN_PATH/$wlsDomainName/servers/admin/security/boot.properties" - echo "password=$wlsPassword" >> "$DOMAIN_PATH/$wlsDomainName/servers/admin/security/boot.properties" + echo "password=$wlsShibboleth" >> "$DOMAIN_PATH/$wlsDomainName/servers/admin/security/boot.properties" sudo chown -R $username:$groupname $DOMAIN_PATH/$wlsDomainName/servers echo "Completed admin server boot properties" } @@ -221,9 +271,10 @@ Wants=network-online.target [Service] Type=simple -WorkingDirectory="/u01/domains/$wlsDomainName" -ExecStart="${startWebLogicScript}" -ExecStop="${stopWebLogicScript}" +WorkingDirectory=/u01/domains +Environment="JAVA_OPTIONS=${SERVER_STARTUP_ARGS}" +ExecStart=/bin/bash ${startWebLogicScript} +ExecStop=/bin/bash ${stopWebLogicScript} User=oracle Group=oracle KillMode=process @@ -264,22 +315,6 @@ do done } -#Function to deploy application in offline mode -#Sample shopping cart -function deploy_sampleApp() -{ - create_app_deploy_model - echo "Downloading and Deploying Sample Application" - wget -q $samplApp - sudo unzip -o shoppingcart.zip -d $DOMAIN_PATH - sudo chown -R $username:$groupname $DOMAIN_PATH/shoppingcart.* - runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; $DOMAIN_PATH/weblogic-deploy/bin/deployApps.sh -oracle_home $oracleHome -archive_file $DOMAIN_PATH/shoppingcart.war -domain_home $DOMAIN_PATH/$wlsDomainName -model_file $DOMAIN_PATH/deploy-app.yaml" - if [[ $? != 0 ]]; then - echo "Error : Deploying application failed" - exit 1 - fi -} - function validateInput() { if [ -z "$wlsDomainName" ]; @@ -288,9 +323,9 @@ function validateInput() exit 1 fi - if [[ -z "$wlsUserName" || -z "$wlsPassword" ]] + if [[ -z "$wlsUserName" || -z "$wlsShibboleth" ]] then - echo_stderr "wlsUserName or wlsPassword is required. " + echo_stderr "wlsUserName or wlsShibboleth is required. " exit 1 fi @@ -340,6 +375,24 @@ function validateInput() exit 1 fi fi + + if [ -z "$virtualNetworkNewOrExisting" ]; + then + echo_stderr "virtualNetworkNewOrExisting is required. " + exit 1 + fi + + if [ -z "$storageAccountPrivateIp" ]; + then + echo_stderr "storageAccountPrivateIp is required. " + exit 1 + fi + + if [ -z "${fileShareName}" ]; + then + echo_stderr "fileShareName is required. " + exit 1 + fi } function enableAndStartAdminServerService() @@ -396,6 +449,9 @@ function validateSSLKeyStores() exit 1 fi + # Verify Identity keystore validity period more than MIN_CERT_VALIDITY + verifyCertValidity $customIdentityKeyStoreFileName $customIdentityKeyStorePassPhrase $CURRENT_DATE $MIN_CERT_VALIDITY $customIdentityKeyStoreType + #validate Trust keystore runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $customTrustKeyStoreFileName -storepass $customTrustKeyStorePassPhrase -storetype $customTrustKeyStoreType | grep 'Entry type:' | grep 'trustedCertEntry'" @@ -404,6 +460,9 @@ function validateSSLKeyStores() exit 1 fi + # Verify Identity keystore validity period more than MIN_CERT_VALIDITY + verifyCertValidity $customTrustKeyStoreFileName $customTrustKeyStorePassPhrase $CURRENT_DATE $MIN_CERT_VALIDITY $customTrustKeyStoreType + echo "ValidateSSLKeyStores Successfull !!" } @@ -458,27 +517,129 @@ function mountFileShare() fi echo "chmod 600 /etc/smbcredentials/${storageAccountName}.cred" sudo chmod 600 /etc/smbcredentials/${storageAccountName}.cred - echo "//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred ,dir_mode=0777,file_mode=0777,serverino" - sudo bash -c "echo \"//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred ,dir_mode=0777,file_mode=0777,serverino\" >> /etc/fstab" - echo "mount -t cifs //${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino" - sudo mount -t cifs //${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino + echo "//${storageAccountPrivateIp}/${fileShareName} $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino" + sudo bash -c "echo \"//${storageAccountPrivateIp}/${fileShareName} $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino\" >> /etc/fstab" + echo "mount -t cifs //${storageAccountPrivateIp}/${fileShareName} $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino" + sudo mount -t cifs //${storageAccountPrivateIp}/${fileShareName} $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino if [[ $? != 0 ]]; then - echo "Failed to mount //${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath" + echo "Failed to mount //${storageAccountPrivateIp}/${fileShareName} $mountpointPath" exit 1 fi } +#this function set the umask 027 (chmod 740) as required by WebLogic security checks +function setUMaskForSecurityDir() +{ + echo "setting umask 027 (chmod 740) for domain/admin security directory" + + if [ -f "$DOMAIN_PATH/$wlsDomainName/servers/$wlsServerName/security/boot.properties" ]; + then + runuser -l oracle -c "chmod 740 $DOMAIN_PATH/$wlsDomainName/servers/$wlsServerName/security/boot.properties" + fi + + if [ -d "$DOMAIN_PATH/$wlsDomainName/servers/$wlsServerName/security" ]; + then + runuser -l oracle -c "chmod 740 $DOMAIN_PATH/$wlsDomainName/servers/$wlsServerName/security" + fi + +} + +#this function checks if remote Anonymous T3/RMI Attributes are available as part of domain security configuration +function containsRemoteAnonymousT3RMIIAttribs() +{ + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; $DOMAIN_PATH/weblogic-deploy/bin/modelHelp.sh -oracle_home $oracleHome topology:/SecurityConfiguration | grep RemoteAnonymousRmiiiopEnabled" >> /dev/null + + result1=$? + + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; $DOMAIN_PATH/weblogic-deploy/bin/modelHelp.sh -oracle_home $oracleHome topology:/SecurityConfiguration | grep RemoteAnonymousRmit3Enabled" >> /dev/null + + result2=$? + + if [ $result1 == 0 ] && [ $result2 == 0 ]; then + echo "true" + else + echo "false" + fi +} + +function generateCustomHostNameVerifier() +{ + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME} + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/test/java + cp ${BASE_DIR}/generateCustomHostNameVerifier.sh ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh + cp ${BASE_DIR}/WebLogicCustomHostNameVerifier.java ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java/WebLogicCustomHostNameVerifier.java + cp ${BASE_DIR}/HostNameValuesTemplate.txt ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java/HostNameValuesTemplate.txt + cp ${BASE_DIR}/WebLogicCustomHostNameVerifierTest.java ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/test/java/WebLogicCustomHostNameVerifierTest.java + chown -R $username:$groupname ${CUSTOM_HOSTNAME_VERIFIER_HOME} + chmod +x ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh + + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh ${wlsAdminHost} ${adminPublicHostName} ${adminPublicHostName} ${dnsLabelPrefix} ${wlsDomainName} ${location}" +} + +function copyCustomHostNameVerifierJarsToWebLogicClasspath() +{ + runuser -l oracle -c "cp ${CUSTOM_HOSTNAME_VERIFIER_HOME}/output/*.jar $oracleHome/wlserver/server/lib/;" + + echo "Modify WLS CLASSPATH to include hostname verifier jars...." + sed -i 's;^WEBLOGIC_CLASSPATH="${WL_HOME}/server/lib/postgresql.*;&\nWEBLOGIC_CLASSPATH="${WL_HOME}/server/lib/hostnamevalues.jar:${WL_HOME}/server/lib/weblogicustomhostnameverifier.jar:${WEBLOGIC_CLASSPATH}";' $oracleHome/oracle_common/common/bin/commExtEnv.sh + echo "Modified WLS CLASSPATH to include hostname verifier jars." +} + + +function configureCustomHostNameVerifier() +{ + echo "configureCustomHostNameVerifier for domain $wlsDomainName for server $wlsServerName" + cat <$DOMAIN_PATH/configureCustomHostNameVerifier.py +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') +try: + edit("$wlsServerName") + startEdit() + + cd('/Servers/$wlsServerName/SSL/$wlsServerName') + cmo.setHostnameVerifier('com.oracle.azure.weblogic.security.util.WebLogicCustomHostNameVerifier') + cmo.setHostnameVerificationIgnored(false) + cmo.setTwoWaySSLEnabled(false) + cmo.setClientCertificateEnforced(false) + + save() + activate() +except Exception,e: + print e + print "Failed to configureCustomHostNameVerifier for domain $wlsDomainName" + dumpStack() + raise Exception('Failed to configureCustomHostNameVerifier for domain $wlsDomainName') +disconnect() +EOF +sudo chown -R $username:$groupname $DOMAIN_PATH +runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST $DOMAIN_PATH/configureCustomHostNameVerifier.py" +if [[ $? != 0 ]]; then + echo "Error : Failed to configureCustomHostNameVerifier for domain $wlsDomainName" + exit 1 +fi + +} #main script starts here + +SCRIPT_PWD=`pwd` CURR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" BASE_DIR="$(readlink -f ${CURR_DIR})" +# Used for certificate expiry validation +CURRENT_DATE=`date +%s` +# Supplied certificate to have minimum days validity for the deployment +MIN_CERT_VALIDITY="1" + + #read arguments from stdin -read wlsDomainName wlsUserName wlsPassword wlsAdminHost oracleHome storageAccountName storageAccountKey mountpointPath isHTTPAdminListenPortEnabled adminPublicHostName isCustomSSLEnabled customIdentityKeyStoreData customIdentityKeyStorePassPhrase customIdentityKeyStoreType customTrustKeyStoreData customTrustKeyStorePassPhrase customTrustKeyStoreType serverPrivateKeyAlias serverPrivateKeyPassPhrase +read wlsDomainName wlsUserName wlsShibboleth wlsAdminHost oracleHome storageAccountName storageAccountKey mountpointPath isHTTPAdminListenPortEnabled adminPublicHostName dnsLabelPrefix location virtualNetworkNewOrExisting storageAccountPrivateIp fileShareName isCustomSSLEnabled customIdentityKeyStoreData customIdentityKeyStorePassPhrase customIdentityKeyStoreType customTrustKeyStoreData customTrustKeyStorePassPhrase customTrustKeyStoreType serverPrivateKeyAlias serverPrivateKeyPassPhrase +wlsServerName="admin" DOMAIN_PATH="/u01/domains" +CUSTOM_HOSTNAME_VERIFIER_HOME="/u01/app/custom-hostname-verifier" startWebLogicScript="${DOMAIN_PATH}/${wlsDomainName}/startWebLogic.sh" stopWebLogicScript="${DOMAIN_PATH}/${wlsDomainName}/bin/customStopWebLogic.sh" @@ -488,8 +649,8 @@ installUtilities mountFileShare +SERVER_STARTUP_ARGS="-Dlog4j2.formatMsgNoLookups=true" KEYSTORE_PATH="${DOMAIN_PATH}/${wlsDomainName}/keystores" -samplApp="https://www.oracle.com/webfolder/technetwork/tutorials/obe/fmw/wls/10g/r3/cluster/session_state/files/shoppingcart.zip" wlsAdminPort=7001 wlsSSLAdminPort=7002 wlsAdminT3ChannelPort=7005 @@ -504,14 +665,10 @@ fi username="oracle" groupname="oracle" -SCRIPT_PWD=`pwd` - create_adminDomain createStopWebLogicScript -deploy_sampleApp - cleanup updateNetworkRules @@ -520,8 +677,18 @@ create_adminserver_service admin_boot_setup +generateCustomHostNameVerifier + +copyCustomHostNameVerifierJarsToWebLogicClasspath + +setUMaskForSecurityDir + enableAndStartAdminServerService echo "Waiting for admin server to be available" wait_for_admin echo "Weblogic admin server is up and running" + +configureCustomHostNameVerifier + +cleanup diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/updateDNSZones.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/updateDNSZones.sh index 2185aa0bd..78f21e8a2 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/updateDNSZones.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/scripts/updateDNSZones.sh @@ -5,38 +5,40 @@ # Description # This script updates the Azure DNS Zones used for configuring DNS for WebLogic Admin Server and Azure Application Gateway. -resourceGroup=$1 -zoneName=$2 -recordSetNames=$3 -targetResources=$4 -lenRecordset=$5 -lenTargets=$6 -ttl=${7} -cnameRecordSetNames=${8} -cnameAlias=${9} -lenCnameRecordSetNames=${10} -lenCnameAlias=${11} - -if [[ ${lenRecordset} != ${lenTargets} ]]; then +# Inputs: +# RESOURCE_GROUP_NAME +# DNS_ZONE_NAME +# DNS_RECORDSET_NAMES +# DNS_TARGET_RESOURCES +# DNS_RECORD_NAMES_LENGTH +# DNS_TARGET_RESOURCES_LENGTH +# DNS_RECORD_TTL +# DNS_CNAME_RECORDSET_NAMES +# DNS_CNAME_ALIAS +# DNS_CNAME_RECORDSET_LENGTH +# DNS_CNAME_ALIAS_LENGTH +# MANAGED_IDENTITY_ID + +if [[ ${DNS_RECORD_NAMES_LENGTH} != ${DNS_TARGET_RESOURCES_LENGTH} ]]; then echo "Error: number of A record set names is not equal to that of target resources." exit 1 fi -if [[ ${lenCnameRecordSetNames} != ${lenCnameAlias} ]]; then +if [[ ${DNS_CNAME_RECORDSET_LENGTH} != ${DNS_CNAME_ALIAS_LENGTH} ]]; then echo "Error: number of CNAME record set names is not equal to that of alias." exit 1 fi # check if the zone exist -az network dns zone show -g ${resourceGroup} -n ${zoneName} +az network dns zone show -g ${RESOURCE_GROUP_NAME} -n ${DNS_ZONE_NAME} # query name server for testing -nsforTest=$(az network dns record-set ns show -g ${resourceGroup} -z ${zoneName} -n @ --query "nsRecords"[0].nsdname -o tsv) +nsforTest=$(az network dns record-set ns show -g ${RESOURCE_GROUP_NAME} -z ${DNS_ZONE_NAME} -n @ --query "nsRecords"[0].nsdname -o tsv) echo name server: ${nsforTest} -if [ ${lenRecordset} -gt 0 ]; then - recordSetNamesArr=$(echo $recordSetNames | tr "," "\n") - targetResourcesArr=$(echo $targetResources | tr "," "\n") +if [ ${DNS_RECORD_NAMES_LENGTH} -gt 0 ]; then + recordSetNamesArr=$(echo $DNS_RECORDSET_NAMES | tr "," "\n") + targetResourcesArr=$(echo $DNS_TARGET_RESOURCES | tr "," "\n") index=0 for record in $recordSetNamesArr; do @@ -45,13 +47,13 @@ if [ ${lenRecordset} -gt 0 ]; then if [ $count -eq $index ]; then echo Create A record with name: $record, target IP: $target az network dns record-set a create \ - -g ${resourceGroup} \ - -z ${zoneName} \ + -g ${RESOURCE_GROUP_NAME} \ + -z ${DNS_ZONE_NAME} \ -n ${record} \ --target-resource ${target} \ - --ttl ${ttl} + --ttl ${DNS_RECORD_TTL} - nslookup ${record}.${zoneName} ${nsforTest} + nslookup ${record}.${DNS_ZONE_NAME} ${nsforTest} if [ $? -eq 1 ];then echo Error: failed to create record with name: $record, target Id: $target exit 1 @@ -65,9 +67,9 @@ if [ ${lenRecordset} -gt 0 ]; then done fi -if [ ${lenCnameRecordSetNames} -gt 0 ];then - cnameRecordSetArr=$(echo $cnameRecordSetNames | tr "," "\n") - cnameRecordAliasArr=$(echo $cnameAlias | tr "," "\n") +if [ ${DNS_CNAME_RECORDSET_LENGTH} -gt 0 ];then + cnameRecordSetArr=$(echo $DNS_CNAME_RECORDSET_NAMES | tr "," "\n") + cnameRecordAliasArr=$(echo $DNS_CNAME_ALIAS | tr "," "\n") index=0 for record in $cnameRecordSetArr; do @@ -76,18 +78,18 @@ if [ ${lenCnameRecordSetNames} -gt 0 ];then if [ $count -eq $index ]; then echo Create CNAME record with name: $record, alias: $target az network dns record-set cname create \ - -g ${resourceGroup} \ - -z ${zoneName} \ + -g ${RESOURCE_GROUP_NAME} \ + -z ${DNS_ZONE_NAME} \ -n ${record} \ - --ttl ${ttl} + --ttl ${DNS_RECORD_TTL} az network dns record-set cname set-record \ - -g ${resourceGroup} \ - -z ${zoneName} \ + -g ${RESOURCE_GROUP_NAME} \ + -z ${DNS_ZONE_NAME} \ --cname ${target} \ --record-set-name ${record} - nslookup ${record}.${zoneName} ${nsforTest} + nslookup ${record}.${DNS_ZONE_NAME} ${nsforTest} if [ $? -eq 1 ];then echo Error: failed to create CNAME record with name: $record, alia: $target exit 1 @@ -100,3 +102,7 @@ if [ ${lenCnameRecordSetNames} -gt 0 ];then index=$((index + 1)) done fi + +# delete user assigned managed identity + +az identity delete --ids ${MANAGED_IDENTITY_ID} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/data/parameters-test.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/data/parameters-test.json deleted file mode 100644 index fcee237ce..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/data/parameters-test.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "adminUsername": { - "value": "weblogic" - }, - "adminPasswordOrKey": { - "value": "#adminPasswordOrKey#" - }, - "dnsLabelPrefix": { - "value": "wls" - }, - "wlsDomainName": { - "value": "#wlsdomainname#" - }, - "wlsUserName": { - "value": "#wlsusername#" - }, - "wlsPassword": { - "value": "#wlspassword#" - }, - "adminVMName": { - "value": "#adminvmname#" - }, - "vmSizeSelect": { - "value": "Standard_D2as_v4" - }, - "location": { - "value": "#location#" - }, - "skuUrnVersion": { - "value": "#skuUrnVersion#" - }, - "_artifactsLocation": { - "value": "https://raw.githubusercontent.com/#gitUserName#/arm-oraclelinux-wls-admin/#testbranchName#/src/main/arm/" - } - } -} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-aad.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-aad.sh deleted file mode 100644 index 0f6ecc87c..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-aad.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. - -#read arguments from stdin -read parametersPath githubUserName testbranchName - -cat < ${parametersPath} -{ - "\$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "_artifactsLocation": { - "value": "https://raw.githubusercontent.com/${githubUserName}/arm-oraclelinux-wls-admin/${testbranchName}/src/main/arm/" - }, - "_artifactsLocationSasToken": { - "value": "" - }, - "aadsPortNumber": { - "value": "636" - }, - "aadsPublicIP": { - "value": "GEN-UNIQUE" - }, - "aadsServerHost": { - "value": "GEN-UNIQUE" - }, - "adminPasswordOrKey": { - "value": "GEN-UNIQUE" - }, - "adminUsername": { - "value": "GEN-UNIQUE" - }, - "enableAAD": { - "value": true - }, - "enableDB": { - "value": false - }, - "vmSizeSelect": { - "value": "Standard_D2as_v4" - }, - "wlsLDAPGroupBaseDN": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPPrincipal": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPPrincipalPassword": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPProviderName": { - "value": "AzureActiveDirectoryProvider" - }, - "wlsLDAPSSLCertificate": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPUserBaseDN": { - "value": "GEN-UNIQUE" - }, - "wlsPassword": { - "value": "GEN-UNIQUE" - }, - "wlsUserName": { - "value": "GEN-UNIQUE" - }, - "enableCustomSSL": { - "value": false - } - } -} -EOF diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-db-aad.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-db-aad.sh deleted file mode 100644 index a9100ecfc..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-db-aad.sh +++ /dev/null @@ -1,87 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. - -#read arguments from stdin -read parametersPath githubUserName testbranchName - -cat < ${parametersPath} -{ - "\$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "_artifactsLocation": { - "value": "https://raw.githubusercontent.com/${githubUserName}/arm-oraclelinux-wls-admin/${testbranchName}/src/main/arm/" - }, - "_artifactsLocationSasToken": { - "value": "" - }, - "aadsPortNumber": { - "value": "636" - }, - "aadsPublicIP": { - "value": "GEN-UNIQUE" - }, - "aadsServerHost": { - "value": "GEN-UNIQUE" - }, - "adminPasswordOrKey": { - "value": "GEN-UNIQUE" - }, - "adminUsername": { - "value": "GEN-UNIQUE" - }, - "databaseType": { - "value": "postgresql" - }, - "dbPassword": { - "value": "GEN-UNIQUE" - }, - "dbUser": { - "value": "GEN-UNIQUE" - }, - "dsConnectionURL": { - "value": "GEN-UNIQUE" - }, - "enableAAD": { - "value": true - }, - "enableDB": { - "value": true - }, - "jdbcDataSourceName": { - "value": "jdbc/postgresql" - }, - "vmSizeSelect": { - "value": "Standard_D2as_v4" - }, - "wlsLDAPGroupBaseDN": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPPrincipal": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPPrincipalPassword": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPProviderName": { - "value": "AzureActiveDirectoryProvider" - }, - "wlsLDAPSSLCertificate": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPUserBaseDN": { - "value": "GEN-UNIQUE" - }, - "wlsPassword": { - "value": "GEN-UNIQUE" - }, - "wlsUserName": { - "value": "GEN-UNIQUE" - }, - "enableCustomSSL": { - "value": false - } - } -} -EOF diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-db.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-db.sh index 4ecb474aa..c5b38edc1 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-db.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-db.sh @@ -3,15 +3,15 @@ # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. #read arguments from stdin -read parametersPath githubUserName testbranchName +read parametersPath repoPath testbranchName cat < ${parametersPath} { - "\$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "\$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "_artifactsLocation": { - "value": "https://raw.githubusercontent.com/${githubUserName}/arm-oraclelinux-wls-admin/${testbranchName}/src/main/arm/" + "value": "https://raw.githubusercontent.com/${repoPath}/${testbranchName}/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/" }, "_artifactsLocationSasToken": { "value": "" @@ -34,17 +34,14 @@ cat < ${parametersPath} "dsConnectionURL": { "value": "GEN-UNIQUE" }, - "enableAAD": { - "value": false - }, "enableDB": { "value": true }, "jdbcDataSourceName": { "value": "jdbc/postgresql" }, - "vmSizeSelect": { - "value": "Standard_D2as_v4" + "vmSize": { + "value": "Standard_B2ms" }, "wlsPassword": { "value": "GEN-UNIQUE" diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-deploy-elk.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-deploy-elk.sh deleted file mode 100644 index 8f7117e13..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-deploy-elk.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. - -#Generate parameters with value for deploying elk template independently - -#read arguments from stdin -read parametersPath adminVMName elasticsearchPassword elasticsearchURI elasticsearchUserName location wlsDomainName wlsusername wlspassword gitUserName testbranchName guidValue - -cat < ${parametersPath} -{ - "adminVMName":{ - "value": "${adminVMName}" - }, - "elasticsearchEndpoint": { - "value": "${elasticsearchURI}" - }, - "elasticsearchPassword": { - "value": "${elasticsearchPassword}" - }, - "elasticsearchUserName": { - "value": "${elasticsearchUserName}" - }, - "guidValue": { - "value": "${guidValue}" - }, - "location": { - "value": "${location}" - }, - "wlsDomainName": { - "value": "${wlsDomainName}" - }, - "wlsPassword": { - "value": "${wlsPassword}" - }, - "wlsUserName": { - "value": "${wlsUserName}" - }, - "_artifactsLocation":{ - "value": "https://raw.githubusercontent.com/${gitUserName}/arm-oraclelinux-wls-admin/${testbranchName}/src/main/arm/" - } - } -EOF diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-deploy-db.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-deploy.sh similarity index 56% rename from weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-deploy-db.sh rename to weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-deploy.sh index 92d382f0b..ba0fc0ea7 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-deploy-db.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-deploy.sh @@ -5,10 +5,16 @@ #Generate parameters with value for deploying db template independently #read arguments from stdin -read parametersPath adminVMName dbPassword dbName location wlsusername wlspassword gitUserName testbranchName +read parametersPath adminPasswordOrKey skuUrnVersion wlsdomainname adminVMName dbPassword dbAdminUser dbName location wlsusername wlspassword repoPath testbranchName -cat < ${parametersPath}/parameters-deploy-db.json +cat < ${parametersPath}/parameters-deploy.json { + "adminPasswordOrKey": { + "value": "${adminPasswordOrKey}" + }, + "adminUsername": { + "value": "weblogic" + }, "adminVMName":{ "value": "${adminVMName}" }, @@ -19,7 +25,7 @@ cat < ${parametersPath}/parameters-deploy-db.json "value": "${dbPassword}" }, "dbUser": { - "value": "weblogic@${dbName}" + "value": "${dbAdminUser}" }, "dsConnectionURL": { "value": "jdbc:postgresql://${dbName}.postgres.database.azure.com:5432/postgres?sslmode=require" @@ -30,6 +36,15 @@ cat < ${parametersPath}/parameters-deploy-db.json "location": { "value": "${location}" }, + "skuUrnVersion": { + "value": "${skuUrnVersion}" + }, + "vmSize": { + "value": "Standard_B2ms" + }, + "wlsDomainName": { + "value": "${wlsdomainname}" + }, "wlsPassword": { "value": "${wlsPassword}" }, @@ -37,7 +52,7 @@ cat < ${parametersPath}/parameters-deploy-db.json "value": "${wlsUserName}" }, "_artifactsLocation":{ - "value": "https://raw.githubusercontent.com/${gitUserName}/arm-oraclelinux-wls-admin/${testbranchName}/src/main/arm/" + "value": "https://raw.githubusercontent.com/${repoPath}/${testbranchName}/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/" }, } EOF diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-elk.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-elk.sh deleted file mode 100644 index ba2c65e85..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters-elk.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. - -#read arguments from stdin -read parametersPath githubUserName testbranchName - -cat <${parametersPath} -{ - "\$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "_artifactsLocation": { - "value": "https://raw.githubusercontent.com/${githubUserName}/arm-oraclelinux-wls-admin/${testbranchName}/src/main/arm/" - }, - "_artifactsLocationSasToken": { - "value": "" - }, - "adminPasswordOrKey": { - "value": "GEN-UNIQUE" - }, - "adminUsername": { - "value": "GEN-UNIQUE" - }, - "elasticsearchEndpoint": { - "value": "GEN-UNIQUE" - }, - "elasticsearchPassword": { - "value": "GEN-UNIQUE" - }, - "elasticsearchUserName": { - "value": "GEN-UNIQUE" - }, - "enableAAD": { - "value": false - }, - "enableDB": { - "value": false - }, - "enableELK": { - "value": true - }, - "vmSizeSelect": { - "value": "Standard_D2as_v4" - }, - "wlsPassword": { - "value": "GEN-UNIQUE" - }, - "wlsUserName": { - "value": "GEN-UNIQUE" - } - } -} -EOF diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters.sh index c4ceda175..c712c8931 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/gen-parameters.sh @@ -3,15 +3,15 @@ # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. #read arguments from stdin -read parametersPath githubUserName testbranchName +read parametersPath repoPath testbranchName cat < ${parametersPath} { - "\$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "\$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "_artifactsLocation": { - "value": "https://raw.githubusercontent.com/${githubUserName}/arm-oraclelinux-wls-admin/${testbranchName}/src/main/arm/" + "value": "https://raw.githubusercontent.com/${repoPath}/${testbranchName}/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/" }, "_artifactsLocationSasToken": { "value": "" @@ -22,14 +22,11 @@ cat < ${parametersPath} "adminUsername": { "value": "GEN-UNIQUE" }, - "enableAAD": { - "value": false - }, "enableDB": { "value": false }, - "vmSizeSelect": { - "value": "Standard_D2as_v4" + "vmSize": { + "value": "Standard_B2ms" }, "wlsPassword": { "value": "GEN-UNIQUE" diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/parameters-deploy-template.json b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/parameters-deploy-template.json new file mode 100644 index 000000000..4d83ddbc5 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/parameters-deploy-template.json @@ -0,0 +1,68 @@ +{ + "adminPasswordOrKey": { + "value": "${adminPasswordOrKey}" + }, + "adminUsername": { + "value": "weblogic" + }, + "adminVMName": { + "value": "${adminVMName}" + }, + "virtualNetworkNewOrExisting": { + "value": "${virtualNetworkNewOrExisting}" + }, + "virtualNetworkResourceGroupName": { + "value": "${virtualNetworkResourceGroupName}" + }, + "virtualNetworkName": { + "value": "${virtualNetworkName}" + }, + "subnetName": { + "value": "${subnetName}" + }, + "databaseType": { + "value": "${databaseType}" + }, + "dbPassword": { + "value": "${dbPassword}" + }, + "dbUser": { + "value": "${dbUser}" + }, + "dsConnectionURL": { + "value": "${dsConnectionURL}" + }, + "enablePswlessConnection": { + "value": ${enablePswlessConnection} + }, + "enableDB": { + "value": ${enableDB} + }, + "jdbcDataSourceName": { + "value": "jdbc/WebLogicDB" + }, + "location": { + "value": "${location}" + }, + "skuUrnVersion": { + "value": "${skuUrnVersion}" + }, + "vmSize": { + "value": "Standard_B2ms" + }, + "wlsDomainName": { + "value": "${wlsdomainname}" + }, + "wlsPassword": { + "value": "${wlsPassword}" + }, + "wlsUserName": { + "value": "${wlsUserName}" + }, + "_artifactsLocation": { + "value": "https://raw.githubusercontent.com/${repoPath}/${testbranchName}/weblogic-azure-vm/arm-oraclelinux-wls-admin/src/main/arm/" + }, + "dbIdentity": { + "value": ${dbIdentity} + } +} \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/verify-deployments.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/verify-deployments.sh index ff6aa6f84..2ec36ff30 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/verify-deployments.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/verify-deployments.sh @@ -3,7 +3,7 @@ # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. #read arguments from stdin -read prefix location template githubUserName testbranchName scriptsDir +read prefix location template repoPath testbranchName scriptsDir groupName=${prefix}-preflight @@ -13,25 +13,13 @@ az group create --verbose --name $groupName --location ${location} # generate parameters for testing differnt cases parametersList=() # parameters for cluster -bash ${scriptsDir}/gen-parameters.sh <<< "${scriptsDir}/parameters.json $githubUserName $testbranchName" +bash ${scriptsDir}/gen-parameters.sh <<< "${scriptsDir}/parameters.json $repoPath $testbranchName" parametersList+=(${scriptsDir}/parameters.json) # parameters for cluster+db -bash ${scriptsDir}/gen-parameters-db.sh <<< "${scriptsDir}/parameters-db.json $githubUserName $testbranchName" +bash ${scriptsDir}/gen-parameters-db.sh <<< "${scriptsDir}/parameters-db.json $repoPath $testbranchName" parametersList+=(${scriptsDir}/parameters-db.json) -# parameters for cluster+aad -bash ${scriptsDir}/gen-parameters-aad.sh <<< "${scriptsDir}/parameters-aad.json $githubUserName $testbranchName" -parametersList+=(${scriptsDir}/parameters-aad.json) - -# parameters for admin+elk -bash ${scriptsDir}/gen-parameters-elk.sh <<< "${scriptsDir}/parameters-elk.json $githubUserName $testbranchName" -parametersList+=(${scriptsDir}/parameters-elk.json) - -# parameters for cluster+db+aad -bash ${scriptsDir}/gen-parameters-db-aad.sh <<< "${scriptsDir}/parameters-db-aad.json $githubUserName $testbranchName" -parametersList+=(${scriptsDir}/parameters-db-aad.json) - # run preflight tests success=true for parameters in "${parametersList[@]}"; diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/verify-services.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/verify-services.sh index 728f1f8a5..e1332b630 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/verify-services.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/verify-services.sh @@ -1,39 +1,39 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. - -# Verify the service using systemctl status -function verifyServiceStatus() -{ - serviceName=$1 - systemctl status $serviceName | grep "active (running)" - if [[ $? != 0 ]]; then - echo "$serviceName is not in active (running) state" - exit 1 - fi - echo "$serviceName is active (running)" -} - -#Verify the service using systemctl is-active -function verifyServiceActive() -{ - serviceName=$1 - state=$(systemctl is-active $serviceName) - if [[ $state == "active" ]]; then - echo "$serviceName is active" - else - echo "$serviceName is not active" - exit 1 - fi -} - -echo "Testing on admin server" -servicesList="rngd wls_admin" - -for service in $servicesList -do - verifyServiceStatus $service - verifyServiceActive $service -done - -exit 0 +#!/bin/bash +# Copyright (c) 2024, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +# Verify the service using systemctl status +function verifyServiceStatus() +{ + serviceName=$1 + systemctl status $serviceName | grep "active (running)" + if [[ $? != 0 ]]; then + echo "$serviceName is not in active (running) state" + exit 1 + fi + echo "$serviceName is active (running)" +} + +#Verify the service using systemctl is-active +function verifyServiceActive() +{ + serviceName=$1 + state=$(systemctl is-active $serviceName) + if [[ $state == "active" ]]; then + echo "$serviceName is active" + else + echo "$serviceName is not active" + exit 1 + fi +} + +echo "Testing on admin server" +servicesList="rngd wls_admin" + +for service in $servicesList +do + verifyServiceStatus $service + verifyServiceActive $service +done + +exit 0 diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/verify-wls-access.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/verify-wls-access.sh index c0af51526..cc808ac28 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/verify-wls-access.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/verify-wls-access.sh @@ -7,34 +7,21 @@ #read arguments from stdin read adminPublicIP adminPort -isSuccess=false -maxAttempt=5 -attempt=1 +CURL_PARMS="--connect-timeout 60 --max-time 180 --retry 10 --retry-delay 30 --retry-max-time 180 --retry-connrefused" + echo "Verifying http://${adminPublicIP}:${adminPort}/weblogic/ready" -while [ $attempt -le $maxAttempt ] -do - echo "Attempt $attempt :- Checking WebLogic admin server is accessible" - curl http://${adminPublicIP}:${adminPort}/weblogic/ready - if [ $? == 0 ]; then - isSuccess=true - break - fi - attempt=`expr $attempt + 1` - sleep 2m -done +curl ${CURL_PARMS} http://${adminPublicIP}:${adminPort}/weblogic/ready -if [[ $isSuccess == "false" ]]; then +if [[ $? != 0 ]]; then echo "Failed : WebLogic admin server is not accessible" exit 1 else echo "WebLogic admin server is accessible" fi -sleep 1m - # Verifying whether admin console is accessible echo "Checking WebLogic admin console is acessible" -curl http://${adminPublicIP}:${adminPort}/console/ +curl ${CURL_PARMS} http://${adminPublicIP}:${adminPort}/console/ if [[ $? != 0 ]]; then echo "WebLogic admin console is not accessible" exit 1 diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/verify-wls-path.sh b/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/verify-wls-path.sh deleted file mode 100644 index d6ff190af..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-admin/test/scripts/verify-wls-path.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. - -echo "#adminPasswordOrKey#" | sudo -S [ -d "/u01/app/wls/install/oracle/middleware/oracle_home/wlserver/modules" ] && exit 0 -exit 1 diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/.github/workflows/build.yml b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/.github/workflows/build.yml deleted file mode 100644 index 4f23c16b5..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/.github/workflows/build.yml +++ /dev/null @@ -1,999 +0,0 @@ -name: Build and Test -on: - workflow_dispatch: - inputs: - enableELK: - description: 'Specify whether to enable ELK depoyment or not.' - required: true - default: 'false' - # Allows you to run this workflow using GitHub APIs - # PERSONAL_ACCESS_TOKEN= - # REPO_NAME=wls-eng/arm-oraclelinux-wls-cluster - # curl --verbose -XPOST -u "wls-eng:${PERSONAL_ACCESS_TOKEN}" -H "Accept: application/vnd.github.everest-preview+json" -H "Content-Type: application/json" https://api.github.com/repos/${REPO_NAME}/dispatches --data '{"event_type": "production-deploy"}' - repository_dispatch: - -env: - adminConsolePort: 7001 - adminPassword: ${{ secrets.WLS_PASSWORD }} - adminVMName: adminServerVM - azCliVersion: 2.6.0 - dbName: wlsdb${{ github.run_id }}${{ github.run_number }} - elkURI: ${{ secrets.ELK_URI }} - elkUser: ${{ secrets.ELK_USER_NAME }} - elkPassword: ${{ secrets.ELK_PSW }} - gitToken: ${{ secrets.GIT_TOKEN }} - location: eastus - managedServerPrefix: managedServer - managedServerVM: "managedServerVM1" - managedServers: "managedServer1" - nsg: wls-nsg - numberOfInstances: 2 - refArmttk: d97aa57d259e2fc8562e11501b1cf902265129d9 - refJavaee: 6addd99d8bc3f472e040f11c053a37e1ac370229 - repoName: arm-oraclelinux-wls-cluster - resourceGroupForDependency: wlsd-${{ github.run_id }}-${{ github.run_number }} - resourceGroupPrefix: ${{ github.run_id }}-${{ github.run_number }} - testbranchName: cicd-${{ github.run_id }}-${{ github.run_number }} - userEmail: ${{ secrets.USER_EMAIL }} - userName: ${{ secrets.USER_NAME }} - wlsDomainName: wlsd - wlsPassword: ${{ secrets.WLS_PASSWORD }} - wlsUserName: weblogic - wls_admin_services: "rngd wls_admin wls_nodemanager" - wls_managedServer_services: "rngd wls_nodemanager" - -jobs: - preflight: - runs-on: ubuntu-latest - steps: - - name: Checkout azure-javaee-iaas - uses: actions/checkout@v2 - with: - repository: Azure/azure-javaee-iaas - path: azure-javaee-iaas - ref: ${{ env.refJavaee }} - - name: Checkout arm-ttk - uses: actions/checkout@v2 - with: - repository: Azure/arm-ttk - path: arm-ttk - ref: ${{ env.refArmttk }} - - name: Checkout ${{ env.repoName }} - uses: actions/checkout@v2 - with: - path: ${{ env.repoName }} - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 - with: - java-version: 1.8 - - name: Build azure-javaee-iaas - run: mvn -DskipTests clean install --file azure-javaee-iaas/pom.xml - - name: Build and test ${{ env.repoName }} - run: mvn -Ptemplate-validation-tests clean install --file ${{ env.repoName }}/pom.xml - - - name: Checkout ${{ env.repoName }} for test - uses: actions/checkout@v2 - with: - path: ${{ env.repoName }}-dev - - name: Create a new branch with development pids in nestedtemplates - run: | - current=`pwd` - echo "current=${current}" >> $GITHUB_ENV - cd ${{ env.repoName }}-dev/${{ env.repoName }}/src/main/arm/nestedtemplates - git config --global core.longpaths true - git config --global user.email $userEmail - git config --global user.name $userName - echo "create branch $testbranchName" - git checkout -b $testbranchName - rm -r -f $current/${{ env.repoName }}-dev/${{ env.repoName }}/src/main/arm/nestedtemplates/* - cp -r -f $current/${{ env.repoName }}/${{ env.repoName }}/target/arm/nestedtemplates/* $current/${{ env.repoName }}-dev/${{ env.repoName }}/src/main/arm/nestedtemplates/ - git status - git commit -a -m "hard code pids" - git push https://$gitToken@github.com/$userName/${{ env.repoName }}.git -f - - - uses: azure/login@v1 - id: azure-login - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} - - name: Validate deployment templates for different combinations of service integration - id: validate-deployment-templates - run: | - bash ${{ env.repoName }}/test/scripts/verify-deployments.sh <<< "${{ github.run_id }}${{ github.run_number }} ${location} \ - ${{ env.repoName }}/${{ env.repoName }}/target/arm/mainTemplate.json \ - ${userName} ${testbranchName} ${{ env.repoName }}/test/scripts" - - - name: Generate artifact file name and path - id: artifact_file - run: | - version=$(awk '/[^<]+<\/version>/{gsub(/|<\/version>/,"",$1);print $1;exit;}' ${{ env.repoName }}/${{ env.repoName }}/pom.xml) - artifactName=${{ env.repoName }}-$version-arm-assembly - unzip ${{ env.repoName }}/${{ env.repoName }}/target/$artifactName.zip -d ${{ env.repoName }}/${{ env.repoName }}/target/$artifactName - echo "##[set-output name=artifactName;]${artifactName}" - echo "##[set-output name=artifactPath;]${{ env.repoName }}/${{ env.repoName }}/target/$artifactName" - - name: Archive ${{ env.repoName }} template - uses: actions/upload-artifact@v1 - if: success() - with: - name: ${{steps.artifact_file.outputs.artifactName}} - path: ${{steps.artifact_file.outputs.artifactPath}} - - - name: Generate addnode artifact file name and path - id: addnode_artifact_file - run: | - addnode_version=$(awk '/[^<]+<\/version>/{gsub(/|<\/version>/,"",$1);print $1;exit;}' ${{ env.repoName }}/addnode/pom.xml) - addnode_artifactName=${{ env.repoName }}-addnode-$addnode_version-arm-assembly - unzip ${{ env.repoName }}/addnode/target/$addnode_artifactName.zip -d ${{ env.repoName }}/addnode/target/$addnode_artifactName - echo "##[set-output name=addnode_artifactName;]${addnode_artifactName}" - echo "##[set-output name=addnode_artifactPath;]${{ env.repoName }}/addnode/target/$addnode_artifactName" - - name: Archive ${{ env.repoName }} addnode template - uses: actions/upload-artifact@v1 - if: success() - with: - name: ${{steps.addnode_artifact_file.outputs.addnode_artifactName}} - path: ${{steps.addnode_artifact_file.outputs.addnode_artifactPath}} - - - name: Generate delete node artifact file name and path - id: deletenode_artifact_file - run: | - deletenode_version=$(awk '/[^<]+<\/version>/{gsub(/|<\/version>/,"",$1);print $1;exit;}' ${{ env.repoName }}/deletenode/pom.xml) - deletenode_artifactName=${{ env.repoName }}-deletenode-$deletenode_version-arm-assembly - unzip ${{ env.repoName }}/deletenode/target/$deletenode_artifactName.zip -d ${{ env.repoName }}/deletenode/target/$deletenode_artifactName - echo "##[set-output name=deletenode_artifactName;]${deletenode_artifactName}" - echo "##[set-output name=deletenode_artifactPath;]${{ env.repoName }}/deletenode/target/$deletenode_artifactName" - - - name: Archive ${{ env.repoName }} deletenode template - uses: actions/upload-artifact@v1 - if: success() - with: - name: ${{steps.deletenode_artifact_file.outputs.deletenode_artifactName}} - path: ${{steps.deletenode_artifact_file.outputs.deletenode_artifactPath}} - - - name: Generate addnode-coherence artifact file name and path - id: addnode_coherence_artifact_file - run: | - addnode_coherence_version=$(awk '/[^<]+<\/version>/{gsub(/|<\/version>/,"",$1);print $1;exit;}' ${{ env.repoName }}/addnode-coherence/pom.xml) - addnode_coherence_artifactName=${{ env.repoName }}-addnode-coherence-$addnode_coherence_version-arm-assembly - unzip ${{ env.repoName }}/addnode-coherence/target/$addnode_coherence_artifactName.zip -d ${{ env.repoName }}/addnode-coherence/target/$addnode_coherence_artifactName - echo "##[set-output name=addnode_coherence_artifactName;]${addnode_coherence_artifactName}" - echo "##[set-output name=addnode_coherence_artifactPath;]${{ env.repoName }}/addnode-coherence/target/$addnode_coherence_artifactName" - - - name: Archive ${{ env.repoName }} addnode-coherence template - uses: actions/upload-artifact@v1 - if: success() - with: - name: ${{steps.addnode_coherence_artifact_file.outputs.addnode_coherence_artifactName}} - path: ${{steps.addnode_coherence_artifact_file.outputs.addnode_coherence_artifactPath}} - - deploy-dependencies: - if: ${{!(github.event_name == 'schedule' && github.repository_owner != 'wls-eng')}} - needs: preflight - runs-on: ubuntu-latest - steps: - - uses: azure/login@v1 - id: azure-login - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} - - name: Create Resource Group - id: create-resource-group - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "create resource group" ${{ env.resourceGroupForDependency }} - az group create --verbose --name ${{ env.resourceGroupForDependency }} --location ${location} - - - name: Set Up Azure Postgresql to Test dbTemplate - id: setup-postgresql - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "Deploy DB with name " ${{ env.dbName }} - az postgres server create \ - --resource-group ${{ env.resourceGroupForDependency }} \ - --name ${{ env.dbName }} \ - --location ${location} \ - --admin-user weblogic \ - --ssl-enforcement Enabled \ - --public-network-access Enabled \ - --admin-password ${{ env.wlsPassword }} \ - --sku-name B_Gen5_1 - - echo "Allow Access To Azure Services" - az postgres server firewall-rule create \ - -g ${{ env.resourceGroupForDependency }} \ - -s ${{ env.dbName }} \ - -n "AllowAllWindowsAzureIps" \ - --start-ip-address "0.0.0.0" \ - --end-ip-address "0.0.0.0" - - deploy-weblogic-cluster: - if: ${{!(github.event_name == 'schedule' && github.repository_owner != 'wls-eng')}} - needs: deploy-dependencies - runs-on: ubuntu-latest - strategy: - max-parallel: 1 - fail-fast: false - matrix: - images: - [ - "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest", - "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest", - "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest", - "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest", - "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", - ] - steps: - - name: Checkout ${{ env.repoName }} - uses: actions/checkout@v2 - with: - path: ${{ env.repoName }} - - name: Get version information from ${{ env.repoName }}/pom.xml - id: version - run: | - version=$(awk '/[^<]+<\/version>/{gsub(/|<\/version>/,"",$1);print $1;exit;}' ${{ env.repoName }}/${{ env.repoName }}/pom.xml) - echo "version=${version}" >> $GITHUB_ENV - - name: Output artifact name for Download action - id: artifact_file - run: | - artifactName=${{ env.repoName }}-$version-arm-assembly - echo "artifactName=${artifactName}" >> $GITHUB_ENV - echo "##[set-output name=artifactName;]${artifactName}" - - name: Download artifact for deployment - uses: actions/download-artifact@v1 - with: - name: ${{steps.artifact_file.outputs.artifactName}} - - uses: azure/login@v1 - id: azure-login - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} - - name: Get Image SKU - id: image-sku - run: | - imageUrn="${{ matrix.images }}" - sku=${imageUrn%%;*} - echo "sku=${sku}" >> $GITHUB_ENV - echo ${resourceGroupPrefix} - resourceGroup=$(echo "${resourceGroupPrefix}-${sku}" | sed "s/_//g") - echo "resourceGroup=${resourceGroup}" >> $GITHUB_ENV - - name: Create Resource Group - id: create-resource-group - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "create resource group" $resourceGroup - az group create --verbose --name $resourceGroup --location ${location} - - - name: Prepare deployed parameters and test script - id: prepare-deployed-parameters-and-test-script - run: | - echo $managedServerPrefix $numberOfInstances $adminVMName - sed -i "s/#location#/$location/g; \ - s/#adminPasswordOrKey#/$wlsPassword/g; \ - s/#wlsdomainname#/$wlsDomainName/g; \ - s/#wlsusername#/$wlsUserName/g; \ - s/#wlspassword#/$wlsPassword/g; \ - s/#managedserverprefix#/$managedServerPrefix/g; \ - s/#numinstances#/$numberOfInstances/g; \ - s/#adminvmname#/$adminVMName/g; \ - s/#skuUrnVersion#/${{ matrix.images }}/g; \ - s/#testbranchName#/$testbranchName/g; \ - s/#gitUserName#/$userName/g" \ - ${{ env.repoName }}/test/data/parameters-test.json - - sed -i "s/#adminPasswordOrKey#/$wlsPassword/g" \ - ${{ env.repoName }}/test/scripts/verify-wls-path.sh - - sed -i "s/#adminVMName#/$adminVMName/g; \ - s/#adminPasswordOrKey#/$wlsPassword/g; \ - s/#managedServers#/$managedServers/g; \ - s/#wlsUserName#/$wlsUserName/g; \ - s/#wlspassword#/$wlsPassword/g" \ - ${{ env.repoName }}/test/scripts/verify-servers-lifecycle.sh - - - name: Accept Image Terms - id: accept-terms - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "accept terms for " "${{ matrix.images }}" - rawUrn="${{ matrix.images }}" - publisherAndName=$(echo ${rawUrn} | grep -o ";.*:" | sed "s/;//g") - imageVersion=${rawUrn##*;} - az vm image terms accept --urn ${publisherAndName}${sku}:${imageVersion} - - - name: Deploy WebLogic Server Cluster Domain offer - id: deploy-wls-cluster - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - az deployment group create \ - --verbose \ - --resource-group $resourceGroup \ - --name wls-cluster-node \ - --parameters @${{ env.repoName }}/test/data/parameters-test.json \ - --template-file ${artifactName}/mainTemplate.json - - - name: Verify Network Security Group - id: verify-nsg - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "query nsg name, will exit with error if nsg does not exist." - az network nsg show -g $resourceGroup -n ${nsg} --query "name" - - - name: Get IP of build machine - id: get-ip-address - run: | - myIP=$(dig @ns1.google.com TXT o-o.myaddr.l.google.com +short) - echo "myIP=${myIP}" >> $GITHUB_ENV - - - name: Add ip address to security rule to access the wls machine - id: add-ip-to-security-rule - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "query existing source address prefixes" - attempt=0 - toCreateRule101=false - while [[ -z `az network nsg show -g $resourceGroup -n ${nsg} | grep "NRMS-Rule-101"` && $attempt -le 5 ]] - do - if [ $attempt -eq 5 ]; then - toCreateRule101=true - fi - echo "network security group rule NRMS-Rule-101 is not ready" - sleep 1m - attempt=$((attempt + 1)) - done - if [ $toCreateRule101 == true ]; then - az network nsg rule create --name NRMS-Rule-101 \ - --nsg-name ${nsg} \ - --priority 101 \ - --resource-group $resourceGroup \ - --access Allow \ - --destination-address-prefixes "*" \ - --destination-port-ranges 22 43 ${adminConsolePort} \ - --direction Inbound \ - --protocol Tcp \ - --source-address-prefixes $myIP - else - sourceAddressPrefixes=$(az network nsg rule show \ - --resource-group $resourceGroup \ - --nsg-name ${nsg} \ - --name NRMS-Rule-101 \ - --query "sourceAddressPrefixes") - echo "IP of this machine: " ${myIP} - sourceAddressPrefixes=$(echo ${myIP} ${sourceAddressPrefixes} | \ - sed 's/,/ /g; s/\[//g; s/\]//g; s/"//g') - echo ${sourceAddressPrefixes} - az network nsg rule update \ - --resource-group $resourceGroup \ - --nsg-name ${nsg} \ - --name NRMS-Rule-101 \ - --source-address-prefixes $sourceAddressPrefixes \ - --destination-port-ranges 443 22 ${adminConsolePort} - fi - - - name: Restart wls VM - id: restart-wls-wm - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "restart vm to make sure security rule work." - az vm restart -g $resourceGroup -n $adminVMName - - - name: Query public IP of AdminServer VM - id: query-wls-admin-ip - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "query public ip" - publicIP=$(az vm show \ - --resource-group $resourceGroup \ - --name $adminVMName -d \ - --query publicIps -o tsv) - echo "##[set-output name=publicIP;]${publicIP}" - - name: Create environment variable for AdminServer IP - id: env-admin-ip - run: echo "wlsPublicIP=${{steps.query-wls-admin-ip.outputs.publicIP}}" >> $GITHUB_ENV - - - name: Query public IP of managedServerVM1 - id: query-wls-managed-ip - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "query public ip" - publicIP=$(az vm show \ - --resource-group $resourceGroup \ - --name $managedServerVM -d \ - --query publicIps -o tsv) - echo "##[set-output name=publicIP;]${publicIP}" - - name: Create environment variable for managedServerVM1 IP - id: env-managedserver-vm1-ip - run: echo "ms1PublicIP=${{steps.query-wls-managed-ip.outputs.publicIP}}" >> $GITHUB_ENV - - - name: Verify WebLogic Server Installation - id: verify-wls - run: | - echo "pubilc IP of wls machine: ${wlsPublicIP}" - echo "Verifying Weblgic server installation" - timeout 6m sh -c 'until nc -zv $0 $1; do echo "nc rc: $?"; sleep 5; done' ${wlsPublicIP} 22 - echo install sshpass - sudo apt-get install -y sshpass - sshpass -p ${wlsPassword} -v ssh -p 22 -o StrictHostKeyChecking=no -o ConnectTimeout=100 -v -tt weblogic@${wlsPublicIP} 'bash -s' < ${{ env.repoName }}/test/scripts/verify-wls-path.sh - - # Fix failure that caused by remote server closed. - - name: Restart remote SSH agent - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "Restart remote SSH agent" - az vm user reset-ssh \ - --resource-group $resourceGroup \ - --name ${{ env.adminVMName }} - - - name: Verify wls admin services - id: veriy-admin-service - run: | - echo "Verifying WebLogic services at admin server" - sshpass -p ${wlsPassword} -v ssh -p 22 -o StrictHostKeyChecking=no -o ConnectTimeout=100 -v -tt weblogic@${wlsPublicIP} 'bash -s' < ${{ env.repoName }}/test/scripts/verify-services.sh $wls_admin_services - - # Fix failure that caused by remote server closed. - - name: Restart remote SSH agent - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "Restart remote SSH agent" - az vm user reset-ssh \ - --resource-group $resourceGroup \ - --name ${{ env.adminVMName }} - - - name: Verify wls managed server services - id: veriy-msservice - run: | - echo "Verifying WebLogic services at managed server" - sshpass -p ${wlsPassword} -v ssh -p 22 -o StrictHostKeyChecking=no -o ConnectTimeout=100 -v -tt weblogic@${ms1PublicIP} 'bash -s' < ${{ env.repoName }}/test/scripts/verify-services.sh $wls_managedServer_services - - - name: Verify WebLogic Server Access - id: verify-wls-access - run: | - echo "Verifying Weblogic Server Access" - bash ${{ env.repoName }}/test/scripts/verify-wls-access.sh <<< "$wlsPublicIP ${adminConsolePort} $wlsUserName $wlsPassword $managedServers" - - # Fix failure that caused by remote server closed. - - name: Restart remote SSH agent - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "Restart remote SSH agent" - az vm user reset-ssh \ - --resource-group $resourceGroup \ - --name ${{ env.adminVMName }} - - - name: Verify WebLogic Managed Server LifeCycle check - id: verify-server-lifecycle - run: | - echo "Verifying Weblogic managed server lifecycle" - sshpass -p ${wlsPassword} -v ssh -p 22 -o StrictHostKeyChecking=no -o ConnectTimeout=100 -v -tt weblogic@${wlsPublicIP} 'bash -s' < ${{ env.repoName }}/test/scripts/verify-servers-lifecycle.sh - - - name: Deploy DB Template to Connect to Azure Postgresql Database - id: enable-postgresql-db - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - # Generate parameters for db template deployment - bash ${{ env.repoName }}/test/scripts/gen-parameters-deploy-db.sh \ - <<< "${{ env.repoName }}/test/scripts/ \ - ${{ env.adminVMName }} \ - ${{ env.wlsPassword}} \ - ${{ env.dbName }} \ - ${{ env.location }} \ - ${{ env.wlsUserName }} \ - ${{ env.wlsPassword }} \ - ${{ env.userName }} \ - ${{ env.testbranchName }}" - echo "Deploy DB Template..." - az group deployment create \ - --verbose \ - --resource-group ${resourceGroup} \ - --name db \ - --parameters @${{ env.repoName }}/test/scripts/parameters-deploy-db.json \ - --template-file ${artifactName}/nestedtemplates/dbTemplate.json - - - name: Generate Application Gateway Certificate - id: gen-certificate-agw - run: | - echo "Generate SSL Certificate for Application Gateway" - openssl genrsa -passout pass:${{ env.wlsPassword }} -out privkey.pem 3072 - openssl req -x509 -new -key privkey.pem -out privkey.pub -subj "/C=US" - openssl pkcs12 -passout pass:${{ env.wlsPassword }} -export -in privkey.pub -inkey privkey.pem -out mycert.pfx - agwCertificateBase64String=$(base64 mycert.pfx -w 0) - echo "agwCertificateBase64String=${agwCertificateBase64String}" >> $GITHUB_ENV - - name: Set up Application Gateway by Deploying Sub Template - id: enable-application-gateway - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - # Generate parameters for application gateway template deployment - bash ${{ env.repoName }}/test/scripts/gen-parameters-deploy-agw.sh \ - <<< "${{ env.repoName }}/test/scripts/parameters-deploy-agw.json \ - ${{ env.userName }} \ - ${{ env.testbranchName }} \ - ${{ env.adminVMName }} \ - ${agwCertificateBase64String} \ - ${{ env.wlsPassword }} \ - ${{ env.numberOfInstances }} \ - ${{ env.location }} \ - ${{ env.wlsPassword }} \ - ${{ env.wlsUserName }} \ - ${{ env.wlsDomainName }} \ - ${{ env.managedServerPrefix }}" - echo "Deploy Application Gateway Template..." - az group deployment create \ - --verbose \ - --debug \ - --resource-group ${resourceGroup} \ - --name agw \ - --parameters @${{ env.repoName }}/test/scripts/parameters-deploy-agw.json \ - --template-file ${artifactName}/nestedtemplates/appGatewayNestedTemplate.json - - - name: Query appGatewayURL of appgateway deployment - id: query-agwurl - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "query appgatewayURL" - appGatewayURL=$(az network public-ip show \ - --resource-group $resourceGroup \ - --name gwip \ - --query dnsSettings.fqdn -o tsv) - echo "##[set-output name=appGatewayURL;]${appGatewayURL}" - - name: Save appGatewayURL for app deployement verification - id: save-appgatewayurl - run: | - echo ${{steps.query-agwurl.outputs.appGatewayURL}} - echo "appGatewayURL=${{steps.query-agwurl.outputs.appGatewayURL}}" >> $GITHUB_ENV - echo ${appGatewayURL} - - - name: Checkout WebLogic-Cafe - id: checkout-webapp - uses: actions/checkout@v2 - with: - repository: microsoft/weblogic-on-azure - path: weblogic-on-azure - - - name: Maven build the web app - id: maven-build-webapp - run: | - echo "build the WebLogic Cafe web app" - mvn -DskipTests clean install --file weblogic-on-azure/javaee/weblogic-cafe/pom.xml - - - name: Query adminVMsver DNS - id: query-adminvmdns - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "query adminVMsver DNS for $adminVMName" - adminVMDNS=$(az network public-ip show \ - --resource-group $resourceGroup \ - --name "${adminVMName}_PublicIP" \ - --query dnsSettings.fqdn -o tsv) - echo "##[set-output name=adminVMDNS;]${adminVMDNS}" - - - name: Save adminVMsver DNS for app deployement - id: save-adminvmdns - run: | - echo ${{steps.query-adminvmdns.outputs.adminVMDNS}} - echo "adminVMDNS=${{steps.query-adminvmdns.outputs.adminVMDNS}}" >> $GITHUB_ENV - echo ${adminVMDNS} - - - name: Prepare the webapp deployment script - id: prepare-webapp-deployement-script - run: | - echo ${adminVMDNS} ${wlsUserName} - sed -i "s/#adminVMDNS#/${adminVMDNS}/g; \ - s/#wlsUserName#/$wlsUserName/g; \ - s/#wlsPassword#/$wlsPassword/g" \ - arm-oraclelinux-wls-cluster/test/scripts/deploy-webapp.sh - - echo ${appGatewayURL} - sed -i "s|#appGatewayURL#|${appGatewayURL}|g;" \ - arm-oraclelinux-wls-cluster/test/scripts/verify-webapp-deployment.sh - - - name: Add ip address to security rule to access the wls machine - id: add-ip-to-security-rule-105 - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "query existing source address prefixes" - attempt=0 - toCreateRule105=false - while [[ -z `az network nsg show -g $resourceGroup -n ${nsg} | grep "NRMS-Rule-105"` && $attempt -le 5 ]] - do - if [ $attempt -eq 5 ]; then - toCreateRule105=true - fi - echo "network security group rule NRMS-Rule-105 is not ready" - sleep 1m - attempt=$((attempt + 1)) - done - if [ $toCreateRule105 == true ]; then - az network nsg rule create --name NRMS-Rule-105 \ - --nsg-name ${nsg} \ - --priority 102 \ - --resource-group $resourceGroup \ - --access Allow \ - --destination-address-prefixes "*" \ - --destination-port-ranges 1433 1434 3306 4333 5432 6379 7000 7199 9042 9160 9300 16379 26379 27017 \ - --direction Inbound \ - --protocol Tcp \ - --source-address-prefixes $myIP - else - az network nsg rule update \ - --resource-group $resourceGroup \ - --nsg-name ${nsg} \ - --name NRMS-Rule-105 \ - --destination-port-ranges 1433 1434 3306 4333 5432 6379 7000 7199 9042 9160 9300 16379 26379 27017 - fi - - - name: Restart wls VM - id: restart-wls-admin-vm - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "restart vm to make sure security rule work." - az vm restart -g $resourceGroup -n $adminVMName - - # Fix failure that caused by remote server closed. - - name: Restart remote SSH agent - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "Restart remote SSH agent" - az vm user reset-ssh \ - --resource-group $resourceGroup \ - --name ${{ env.adminVMName }} - - - name: Deploy WebLogicCafe app using WebLogic Management Services - id: deploy-webapp - run: | - echo "Deploy WebLogic Cafe to server" - timeout 6m sh -c 'until nc -zv $0 $1; do echo "nc rc: $?"; sleep 5; done' ${adminVMDNS} 7001 - bash arm-oraclelinux-wls-cluster/test/scripts/deploy-webapp.sh - - - name: Verify WebLogicCafe app is successfully deployed - id: verify-webapp-deployment - run: | - echo "Verify WebLogicCafe app is successfully deployed" - bash arm-oraclelinux-wls-cluster/test/scripts/verify-webapp-deployment.sh - - - name: Set up ELK by deploying sub template - id: enable-elk - if: ${{github.event_name == 'workflow_dispatch' && github.event.inputs.enableELK == 'true'}} - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - # Generate parameters for ELK template deployment - bash ${{ env.repoName }}/test/scripts/gen-parameters-deploy-elk.sh \ - <<< "${{ env.repoName }}/test/scripts/parameters-deploy-elk.json \ - ${{ env.adminVMName }} \ - ${{ env.elkPassword }} \ - ${{ env.elkURI }} \ - ${{ env.elkUser }} \ - ${{ env.location }} \ - ${{ env.numberOfInstances }} \ - ${{ env.wlsDomainName }} \ - ${{ env.wlsUserName }} \ - ${{ env.wlsPassword }} \ - ${{ env.userName }} \ - ${{ env.testbranchName }} \ - ${{ env.managedServerPrefix }} \ - ${{ github.run_id }}${{ github.run_number }}" - - echo "Deploy ELK Template..." - az group deployment create \ - --debug \ - --resource-group ${resourceGroup} \ - --name elk \ - --parameters @${{ env.repoName }}/test/scripts/parameters-deploy-elk.json \ - --template-file ${artifactName}/nestedtemplates/elkNestedTemplate.json - - - name: Get storage account name - id: query-storage-account-name - run: | - echo "query storage account name" - storageAccount=$(az resource list -g $resourceGroup --resource-type Microsoft.Storage/storageAccounts --query [0].name -o tsv) - echo "Storage account name: ${storageAccount}" - echo "storageAccount=${storageAccount}" >> $GITHUB_ENV - - - name: Set up Coherence by deploying sub template - id: enable-coherence - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - # Generate parameters for Coherence template deployment - bash ${{ env.repoName }}/test/scripts/gen-parameters-deploy-coherence.sh \ - <<< "${{ env.repoName }}/test/scripts/parameters-deploy-coherence.json \ - ${{ env.adminVMName }} \ - ${{ env.wlsPassword }} \ - ${{ matrix.images }} \ - ${{ env.location }} \ - ${storageAccount} \ - ${{ env.wlsDomainName }} \ - ${{ env.wlsUserName }} \ - ${{ env.wlsPassword }} \ - ${{ env.userName }} \ - ${{ env.testbranchName }} \ - ${{ env.managedServerPrefix }}" - - echo "Deploy Coherence Template..." - az group deployment create \ - --debug \ - --resource-group ${resourceGroup} \ - --name coherence \ - --parameters @${{ env.repoName }}/test/scripts/parameters-deploy-coherence.json \ - --template-file ${artifactName}/nestedtemplates/coherenceTemplate.json - - - name: Output addnode artifact name - id: artifact_file_addnode - run: | - addnodeVersion=$(awk '/[^<]+<\/version>/{gsub(/|<\/version>/,"",$1);print $1;exit;}' ${{ env.repoName }}/addnode/pom.xml) - artifactNameOfAddnode=${{ env.repoName }}-addnode-$addnodeVersion-arm-assembly - echo "artifactNameOfAddnode=${artifactNameOfAddnode}" >> $GITHUB_ENV - echo "##[set-output name=artifactNameOfAddnode;]${artifactNameOfAddnode}" - - name: Download artifact for deployment - uses: actions/download-artifact@v1 - with: - name: ${{steps.artifact_file_addnode.outputs.artifactNameOfAddnode}} - - - name: Add new nodes to existing cluster - id: add-node - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "add two new nodes and enable app gateway" - echo "generate add-node parameters" - bash ${{ env.repoName }}/test/scripts/gen-parameters-deploy-addnode.sh \ - <<< "${{ env.repoName }}/test/scripts/parameters-deploy-addnode.json \ - ${{ env.wlsPassword }} \ - ${{ env.adminVMName }}:${adminConsolePort} \ - weblogic \ - ${{ env.numberOfInstances }} \ - ${{ matrix.images }} \ - ${storageAccount} \ - ${{ env.wlsDomainName }} \ - ${{ env.location }} \ - ${{ env.wlsUserName }} \ - ${{ env.wlsPassword }} \ - ${{ env.userName }} \ - ${{ env.testbranchName }} \ - ${{ env.managedServerPrefix }}" - echo "deploy add-node template to create new nodes" - az group deployment validate \ - -g ${resourceGroup} \ - -f ${artifactNameOfAddnode}/mainTemplate.json \ - -p @${{ env.repoName }}/test/scripts/parameters-deploy-addnode.json \ - --no-prompt - az group deployment create \ - --debug \ - --resource-group ${resourceGroup} \ - --name addnode \ - --parameters @${{ env.repoName }}/test/scripts/parameters-deploy-addnode.json \ - --template-file ${artifactNameOfAddnode}/mainTemplate.json - - name: Verify new nodes - id: verify-new-nodes - run: | - mspVM2=$(az resource list -g ${resourceGroup} --resource-type Microsoft.Compute/virtualMachines --name ${{ env.managedServerPrefix }}VM2 --query [0].name -o tsv) - if [ -z "$mspVM2" ]; then - echo "Add-node failure: new machine ${{ env.managedServerPrefix }}VM2 does not exist." - exit 1 - fi - - - name: Output addnode-coherence artifact name - id: artifact_file_addnode_coherence - run: | - addnodeCoherenceVersion=$(awk '/[^<]+<\/version>/{gsub(/|<\/version>/,"",$1);print $1;exit;}' ${{ env.repoName }}/addnode-coherence/pom.xml) - artifactNameOfAddnodeCo=${{ env.repoName }}-addnode-coherence-$addnodeCoherenceVersion-arm-assembly - echo "artifactNameOfAddnodeCo=${artifactNameOfAddnodeCo}" >> $GITHUB_ENV - echo "##[set-output name=artifactNameOfAddnodeCo;]${artifactNameOfAddnodeCo}" - - name: Download artifact for deployment - uses: actions/download-artifact@v1 - with: - name: ${{steps.artifact_file_addnode_coherence.outputs.artifactNameOfAddnodeCo}} - - - name: Add new cache node to coherence cluster - id: add-node-coherence - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "add new cache server" - echo "generate parameters" - bash ${{ env.repoName }}/test/scripts/gen-parameters-deploy-addnode-coherence.sh \ - <<< "${{ env.repoName }}/test/scripts/parameters-deploy-addnode-coherence.json \ - ${{ env.wlsPassword }} \ - ${{ env.adminVMName }} \ - weblogic \ - 1 \ - ${{ matrix.images }} \ - ${storageAccount} \ - ${{ env.wlsDomainName }} \ - ${{ env.location }} \ - ${{ env.wlsUserName }} \ - ${{ env.wlsPassword }} \ - ${{ env.userName }} \ - ${{ env.testbranchName }} \ - ${{ env.managedServerPrefix }}" - echo "deploy add-node template to create new nodes" - az group deployment validate \ - -g ${resourceGroup} \ - -f ${artifactNameOfAddnodeCo}/mainTemplate.json \ - -p @${{ env.repoName }}/test/scripts/parameters-deploy-addnode-coherence.json \ - --no-prompt - az group deployment create \ - --debug \ - --resource-group ${resourceGroup} \ - --name addnode \ - --parameters @${{ env.repoName }}/test/scripts/parameters-deploy-addnode-coherence.json \ - --template-file ${artifactNameOfAddnodeCo}/mainTemplate.json - - name: Verify new nodes - id: verify-new-nodes-coherence - run: | - mspVM2=$(az resource list -g ${resourceGroup} --resource-type Microsoft.Compute/virtualMachines --name ${{ env.managedServerPrefix }}StorageVM2 --query [0].name -o tsv) - if [ -z "$mspVM2" ]; then - echo "Add-node failure: new machine ${{ env.managedServerPrefix }}StorageVM2 does not exist." - exit 1 - fi - - - name: Output delete-node artifact name - id: artifact_file_deletenode - run: | - deleteNodeVersion=$(awk '/[^<]+<\/version>/{gsub(/|<\/version>/,"",$1);print $1;exit;}' ${{ env.repoName }}/deletenode/pom.xml) - artifactNameOfDeleteNode=${{ env.repoName }}-deletenode-$deleteNodeVersion-arm-assembly - echo "artifactNameOfDeleteNode=${artifactNameOfDeleteNode}" >> $GITHUB_ENV - echo "##[set-output name=artifactNameOfDeleteNode;]${artifactNameOfDeleteNode}" - - name: Download artifact for deployment - uses: actions/download-artifact@v1 - with: - name: ${{steps.artifact_file_deletenode.outputs.artifactNameOfDeleteNode}} - - name: Delete nodes from existing cluster - id: delete-node - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "generate delete-node parameters" - bash ${{ env.repoName }}/test/scripts/gen-parameters-deploy-deletenode.sh \ - <<< "${{ env.repoName }}/test/scripts/parameters-deploy-deletenode.json \ - ${{ env.adminVMName }} \ - ${{ env.location }} \ - ${{ env.wlsUserName }} \ - ${{ env.wlsPassword }} \ - ${{ env.userName }} \ - ${{ env.testbranchName }} \ - ${{ env.managedServerPrefix }}" - echo "Run deletenode-cli.sh to remove nodes" - chmod ugo+x ${artifactNameOfDeleteNode}/scripts/deletenode-cli.sh - ${artifactNameOfDeleteNode}/scripts/deletenode-cli.sh \ - -g ${resourceGroup} \ - -f ${artifactNameOfDeleteNode}/mainTemplate.json \ - -p ${{ env.repoName }}/test/scripts/parameters-deploy-deletenode.json \ - -s - - name: Verify deleted nodes - id: verify-deleted-nodes - run: | - mspVM2=$(az resource list -g ${resourceGroup} --resource-type Microsoft.Compute/virtualMachines --name ${{ env.managedServerPrefix }}VM2 --query [0].name -o tsv) - count=0 - while [[ -n "$mspVM2" && $count -lt 10 ]]; - do - echo "waiting for $mspVM2 deleted..." - sleep 1m - count=$((count+1)) - mspVM2=$(az resource list -g ${resourceGroup} --resource-type Microsoft.Compute/virtualMachines --name ${{ env.managedServerPrefix }}VM2 --query [0].name -o tsv) - if [ -z "$mspVM2" ]; then - break; - fi - done - - if [ -n "$mspVM2" ]; then - echo "Delete-node failure: machine ${{ env.managedServerPrefix }}VM2 is not removed." - exit 1 - fi - - - name: Delete Resource Group - id: delete-resource-group - if: always() - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "delete... " $resourceGroup - az group delete --yes --no-wait --verbose --name $resourceGroup - - name: Delete ELK index - id: delete-elk-index - if: ${{github.event_name == 'workflow_dispatch' && github.event.inputs.enableELK == 'true'}} - run: | - curl -XDELETE --user ${{ env.elkUser }}:${{ env.elkPassword }} ${{ env.elkURI }}/azure-weblogic-cluster-${{ github.run_id }}${{ github.run_number }} - - cleanup-github-resoruce: - needs: deploy-weblogic-cluster - if: always() - runs-on: ubuntu-latest - steps: - - name: Checkout ${{ env.repoName }} - uses: actions/checkout@v2 - with: - path: ${{ env.repoName }} - - name: Delete testing branch - run: | - cd ${{ env.repoName }} - git push https://$gitToken@github.com/$userName/${{ env.repoName }}.git -f --delete $testbranchName - - cleanup-az-resource: - if: always() - needs: deploy-weblogic-cluster - runs-on: ubuntu-latest - steps: - - uses: azure/login@v1 - id: azure-login - if: ${{!(github.event_name == 'schedule' && github.repository_owner != 'wls-eng')}} - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} - - name: Delete DB Resource Group - id: delete-db-resource-group - if: ${{!(github.event_name == 'schedule' && github.repository_owner != 'wls-eng')}} - uses: azure/CLI@v1 - with: - azcliversion: ${{ env.azCliVersion }} - inlineScript: | - echo "delete... " $resourceGroup - az group delete --yes --no-wait --verbose --name ${{ env.resourceGroupForDependency }} - - summary: - needs: deploy-weblogic-cluster - if: always() - runs-on: ubuntu-latest - steps: - - name: summarize jobs - if: ${{!(github.event_name == 'schedule' && github.repository_owner != 'wls-eng')}} - run: | - workflow_jobs=$(curl -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/wls-eng/arm-oraclelinux-wls-cluster/actions/runs/${{ github.run_id }}/jobs) - critical_job_num=$(echo $workflow_jobs | jq '.jobs | map(select(.name|test("^deploy-weblogic-cluster."))) | length') - echo "$critical_job_num" - succeed_critical_job_num=$(echo $workflow_jobs | jq '.jobs | map(select(.conclusion=="success") | select(.name|test("^deploy-weblogic-cluster."))) | length') - echo "$succeed_critical_job_num" - failed_job_num="$(($critical_job_num-$succeed_critical_job_num))" - echo $failed_job_num - if (($failed_job_num >= 2));then - echo "too many jobs failed, send notification to Teams" - curl ${{ secrets.MSTEAMS_WEBHOOK }} \ - -H 'Content-Type: application/json' \ - --data-binary @- << EOF - { - "@context":"http://schema.org/extensions", - "@type":"MessageCard", - "text":"$failed_job_num jobs failed in Configured Cluster Offer's workflow, please take a look at: https://github.com/wls-eng/arm-oraclelinux-wls-cluster/actions/runs/${{ github.run_id }}" - } - EOF - fi diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/.github/workflows/newtag.yaml b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/.github/workflows/newtag.yaml deleted file mode 100644 index def24ea6e..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/.github/workflows/newtag.yaml +++ /dev/null @@ -1,104 +0,0 @@ -name: New Tag -on: - workflow_dispatch: - inputs: - tagname: - description: 'Specify Tag name to create/update.' - required: true - default: '2020-12-02-01-Q4' - ref: - description: 'Specify Git Ref if needed.' - required: false - default: 'refs/heads/develop' -env: - tagbranch: "tagbranch" - refArmttk: d97aa57d259e2fc8562e11501b1cf902265129d9 - refJavaee: 6addd99d8bc3f472e040f11c053a37e1ac370229 - gitToken: ${{ secrets.GIT_TOKEN }} - repoName: "arm-oraclelinux-wls-cluster" - userEmail: ${{ secrets.USER_EMAIL }} - userName: ${{ secrets.USER_NAME }} - -jobs: - newtag: - runs-on: ubuntu-latest - steps: - - name: Checkout azure-javaee-iaas - uses: actions/checkout@v2 - with: - repository: Azure/azure-javaee-iaas - path: azure-javaee-iaas - ref: ${{ env.refJavaee }} - - name: Checkout arm-ttk - uses: actions/checkout@v2 - with: - repository: Azure/arm-ttk - path: arm-ttk - ref: ${{ env.refArmttk }} - - name: Checkout ${{ env.repoName }} - uses: actions/checkout@v2 - with: - path: ${{ env.repoName }} - ref: ${{ github.event.inputs.ref }} - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 - with: - java-version: 1.8 - - name: Build azure-javaee-iaas - run: mvn -DskipTests clean install --file azure-javaee-iaas/pom.xml - - - name: Build and test ${{ env.repoName }} - run: | - cd ${{ env.repoName }} - mvn -Ptemplate-validation-tests clean install - - - name: Create new tag - run: | - cd ${{ env.repoName }} - git config --global core.longpaths true - git config --global user.email $userEmail - git config --global user.name $userName - - authGitPath=https://$gitToken@github.com/$userName/${{ env.repoName }}.git - - echo "Create tag branch" - remoteBranches=$(git ls-remote --heads) - echo ${remoteBranches} - if [[ -n `echo ${remoteBranches} | grep "${tagbranch}"` ]]; then - git push ${authGitPath} --delete ${tagbranch} -f - fi - git checkout -b ${tagbranch} - - # replace pids - export targetARM="target/arm" - for d in */ ; do - echo $d - if [ ! -d ${d}${targetARM} ];then - continue; - fi - - list=$(find ${d}${targetARM} | grep ".json") - for file in ${list}; do - targetPath=$(echo "$file" | sed "s:target:src/main:g") - if test -f "$targetPath"; then - echo "Replace ${targetPath} with ${file}" - cp -f $file $targetPath - fi - done - done - - git status - git commit -a -m "hard code pids" - git fetch --unshallow - git push ${authGitPath} tagbranch -f - - # remove existing tag - tagname=${{ github.event.inputs.tagname }} - if [[ -n `git ls-remote --tags | grep "${tagname}"` ]]; then - git push ${authGitPath} --delete ${tagname} -f - fi - - # create new tag - git tag ${tagname} - git push ${authGitPath} ${tagname} -f - git push ${authGitPath} --delete ${tagbranch} -f diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/.github/workflows/package.yaml b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/.github/workflows/package.yaml deleted file mode 100644 index da7f3a918..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/.github/workflows/package.yaml +++ /dev/null @@ -1,73 +0,0 @@ -name: Package ARM -on: - workflow_dispatch: - inputs: - pidType: - description: 'Specify which pids to use, oracle or microsoft.' - required: true - default: 'microsoft' - ref: - description: 'Specify Git Ref if needed.' - required: false - default: 'refs/heads/develop' -env: - refArmttk: d97aa57d259e2fc8562e11501b1cf902265129d9 - refJavaee: 6addd99d8bc3f472e040f11c053a37e1ac370229 - repoName: "arm-oraclelinux-wls-cluster" - -jobs: - package: - runs-on: ubuntu-latest - steps: - - name: Checkout azure-javaee-iaas - uses: actions/checkout@v2 - with: - repository: Azure/azure-javaee-iaas - path: azure-javaee-iaas - ref: ${{ env.refJavaee }} - - name: Checkout arm-ttk - uses: actions/checkout@v2 - with: - repository: Azure/arm-ttk - path: arm-ttk - ref: ${{ env.refArmttk }} - - name: Checkout ${{ env.repoName }} - uses: actions/checkout@v2 - with: - path: ${{ env.repoName }} - ref: ${{ github.event.inputs.ref }} - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 - with: - java-version: 1.8 - - name: Build azure-javaee-iaas - run: mvn -DskipTests clean install --file azure-javaee-iaas/pom.xml - - - name: Build and test ${{ env.repoName }} using ${{ github.event.inputs.pidType }} pids - run: | - cd ${{ env.repoName }} - pidType=${{ github.event.inputs.pidType }} - if [[ "${pidType}" == "oracle" ]];then - echo "using oracle pid" - mvn -Ptemplate-validation-tests clean install - else - echo "using ms pid" - mvn -Ptemplate-validation-tests clean install -Ddev - fi - - - name: Generate artifact file name and path - id: artifact_file - run: | - version=$(awk '/[^<]+<\/version>/{gsub(/|<\/version>/,"",$1);print $1;exit;}' ${{ env.repoName }}/${{ env.repoName }}/pom.xml) - artifactName=${{ env.repoName }}-$version-arm-assembly - unzip ${{ env.repoName }}/${{ env.repoName }}/target/$artifactName.zip -d ${{ env.repoName }}/${{ env.repoName }}/target/$artifactName - echo "##[set-output name=artifactName;]${artifactName}-${{ github.event.inputs.pidType }}" - echo "##[set-output name=artifactPath;]${{ env.repoName }}/${{ env.repoName }}/target/$artifactName" - - name: Archive ${{ env.repoName }} template - uses: actions/upload-artifact@v1 - if: success() - with: - name: ${{steps.artifact_file.outputs.artifactName}} - path: ${{steps.artifact_file.outputs.artifactPath}} - - diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/README.md b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/README.md index b034f5346..c1a10b45a 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/README.md +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/README.md @@ -1,3 +1,8 @@ + + ## WebLogic Server (with N-Node Cluster) on Microsoft Azure - Marketplace Offerings This git repository is used to maintain the Azure Resource Management (ARM) templates and other scripts diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode-coherence/pom.xml b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode-coherence/pom.xml index a367ddd12..a5390bff4 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode-coherence/pom.xml +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode-coherence/pom.xml @@ -1,38 +1,39 @@ - + 4.0.0 - com.oracle.weblogic.azure - arm-oraclelinux-wls-cluster-addnode-coherence - 1.0.0 - - com.microsoft.azure.iaas - azure-javaee-iaas-parent - 1.0.7 - + com.oracle.weblogic.azure + weblogic-azure-vm + 1.0.0 + ../../pom.xml - + + com.oracle.weblogic.azure + arm-oraclelinux-wls-cluster-addnode-coherence + ${version.arm-oraclelinux-wls-cluster-addnode-coherence} + jar ${project.artifactId} - ${basedir}/../../arm-ttk/arm-ttk - -TestParameter '@{"SampleName"="addnode-coherence/src/main";"RawRepoPath"="${artifactsLocationBase}/arm-oraclelinux-wls-cluster/${git.tag}/"}' - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/pid.properties - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/microsoft-pid.properties + -TestParameter '@{"SampleName"="addnode-coherence/src/main";"RawRepoPath"="${artifactsLocationBase}/arm-oraclelinux-wls-cluster/"}' + ${project.basedir}/../../.. + false + false - + diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode-coherence/src/main/arm/addnodedeploy.parameters.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode-coherence/src/main/arm/addnodedeploy.parameters.json index 620516ec5..427809198 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode-coherence/src/main/arm/addnodedeploy.parameters.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode-coherence/src/main/arm/addnodedeploy.parameters.json @@ -29,7 +29,7 @@ "usePreviewImage": { "value": "GEN-UNIQUE" }, - "vmSizeSelectForCoherence": { + "vmSize": { "value": "GEN-UNIQUE" }, "wlsDomainName": { @@ -40,6 +40,12 @@ }, "wlsUserName": { "value": "GEN-UNIQUE" + }, + "enableDNSConfiguration": { + "value": false + }, + "customDNSNameForAdminServer" : { + "value": "GEN-UNIQUE" } } -} \ No newline at end of file +} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode-coherence/src/main/arm/mainTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode-coherence/src/main/arm/mainTemplate.json index 2c94efe40..c3febcf13 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode-coherence/src/main/arm/mainTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode-coherence/src/main/arm/mainTemplate.json @@ -7,7 +7,7 @@ "metadata": { "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." }, - "defaultValue": "${artifactsLocationBase}/arm-oraclelinux-wls-cluster/${git.tag}/addnode-coherence/src/main/" + "defaultValue": "${artifactsLocationBase}/arm-oraclelinux-wls-cluster/addnode-coherence/src/main/" }, "_artifactsLocationSasToken": { "type": "securestring", @@ -112,13 +112,23 @@ }, "skuUrnVersion": { "type": "string", - "defaultValue": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "defaultValue": "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", "allowedValues": [ - "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest", - "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest", + "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", + "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest", + "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest", + "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest", + "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest", + "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest", "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest", "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest", - "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" + "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest", + "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel76;Oracle:weblogic-122140-jdk8-rhel76:owls-122140-jdk8-rhel76;latest", + "owls-141100-jdk8-rhel76;Oracle:weblogic-141100-jdk8-rhel76:owls-141100-jdk8-rhel76;latest", + "owls-141100-jdk11-rhel76;Oracle:weblogic-141100-jdk11-rhel76:owls-141100-jdk11-rhel76;latest" ], "metadata": { "description": "The Oracle Linux image with Weblogic and Java preinstalled. Semicolon separated string of Sku, URN, and Version" @@ -137,13 +147,34 @@ "description": "Bool value, if it's set to true, will deploy with preview weblogic image." } }, - "vmSizeSelectForCoherence": { + "vmSize": { "defaultValue": "Standard_A3", "type": "string", "metadata": { "description": "Select appropriate VM Size for Coherence" } }, + "virtualNetworkName": { + "type": "string", + "defaultValue": "wls-vnet", + "metadata": { + "description": "Name of the existing or new VNET" + } + }, + "virtualNetworkResourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "Resource group of Virtual network" + } + }, + "subnetName": { + "type": "string", + "defaultValue": "wls-subnet", + "metadata": { + "description": "Name of the existing or new Subnet" + } + }, "wlsDomainName": { "type": "string", "defaultValue": "wlsd", @@ -164,6 +195,20 @@ "description": "Username for your Weblogic domain name" } }, + "enableDNSConfiguration": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "Boolean value indicating, if DNS Zone Configuration is enabled or not" + } + }, + "customDNSNameForAdminServer": { + "type": "string", + "defaultValue": "none", + "metadata": { + "description": "Custom DNS Name for WebLogic Admin Server" + } + }, "customSSLSettings": { "type": "secureObject", "defaultValue": { @@ -200,7 +245,7 @@ }, "const_mountPointPath": "[concat('/mnt/', variables('name_share'))]", "const_publicIPAddressType": "Dynamic", - "const_vmSize": "[parameters('vmSizeSelectForCoherence')]", + "const_vmSize": "[parameters('vmSize')]", "const_wlsDomainPath": "/u01/domains", "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", "name_linuxImageOfferSKU": "[first(split(parameters('skuUrnVersion'), ';'))]", @@ -210,11 +255,15 @@ "name_scriptCoherenceFile": "setupCoherence.sh", "name_scriptELKConfiguration": "elkIntegration.sh", "name_share": "wlsshare", - "name_subnet": "Subnet", - "name_virtualNetwork": "[concat(parameters('wlsDomainName'),'_VNET')]", + "name_subnet": "[parameters('subnetName')]", + "name_virtualNetwork": "[parameters('virtualNetworkName')]", "name_vmMachine": "[concat(parameters('managedServerPrefix'),'StorageVM')]", "name_wlsServerPrefix": "[concat(parameters('managedServerPrefix'),'Storage')]", - "ref_subnet": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]" + "ref_subnet": "[resourceId(parameters('virtualNetworkResourceGroupName'), 'Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]", + "name_customHostnameGeneratorscriptFile": "generateCustomHostNameVerifier.sh", + "name_customHostnameVerifierJavaFile": "src/main/java/WebLogicCustomHostNameVerifier.java", + "name_customHostnameValuesTemplate": "src/main/java/HostNameValuesTemplate.txt", + "name_customHostnameVerifierTest" : "src/test/java/WebLogicCustomHostNameVerifierTest.java" }, "functions": [ { @@ -237,7 +286,7 @@ ], "resources": [ { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${cluster.addnode.coherence.start}", "type": "Microsoft.Resources/deployments", "properties": { @@ -251,8 +300,8 @@ } }, { + "apiVersion": "${azure.apiVersionForPublicIPAddresses}", "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_vmMachine'),copyIndex(variables('const_cacheServerIndexOffset')),variables('name_publicIPAddress'))]", "location": "[parameters('location')]", "copy": { @@ -267,14 +316,14 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualNetworks}", "type": "Microsoft.Network/virtualNetworks/subnets", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_virtualNetwork'), '/', variables('name_subnet'))]", "condition": "[and(empty(variables('name_virtualNetwork')), empty(variables('name_subnet')))]" }, { + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_vmMachine'), copyIndex(variables('const_cacheServerIndexOffset')), variables('name_nic'))]", "location": "[parameters('location')]", "copy": { @@ -305,8 +354,8 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_vmMachine'), copyIndex(variables('const_cacheServerIndexOffset')))]", "location": "[parameters('location')]", "copy": { @@ -338,17 +387,7 @@ "managedDisk": { "storageAccountType": "Standard_LRS" } - }, - "dataDisks": [ - { - "lun": 0, - "createOption": "FromImage", - "diskSizeGB": 900, - "managedDisk": { - "storageAccountType": "Standard_LRS" - } - } - ] + } }, "networkProfile": { "networkInterfaces": [ @@ -360,7 +399,7 @@ "diagnosticsProfile": { "bootDiagnostics": { "enabled": true, - "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', parameters('storageAccountName')), '${azure.apiVersion2}').primaryEndpoints.blob]" + "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', parameters('storageAccountName')), '${azure.apiVersionForStorage}').primaryEndpoints.blob]" } } }, @@ -371,9 +410,9 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines/extensions", "name": "[concat(variables('name_vmMachine'), copyIndex(variables('const_cacheServerIndexOffset')),'/newuserscript')]", - "apiVersion": "${azure.apiVersion}", "location": "[parameters('location')]", "copy": { "name": "virtualMachineExtensionLoop", @@ -390,16 +429,20 @@ "settings": { "fileUris": [ "[uri(parameters('_artifactsLocation'), concat('../../../arm-oraclelinux-wls-cluster/src/main/scripts/', variables('name_scriptCoherenceFile'), parameters('_artifactsLocationSasToken')))]", - "[uri(parameters('_artifactsLocation'), concat('../../../arm-oraclelinux-wls-cluster/src/main/scripts/', variables('name_scriptELKConfiguration'), parameters('_artifactsLocationSasToken')))]" + "[uri(parameters('_artifactsLocation'), concat('../../../arm-oraclelinux-wls-cluster/src/main/scripts/', variables('name_scriptELKConfiguration'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameGeneratorscriptFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierJavaFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameValuesTemplate'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierTest'), parameters('_artifactsLocationSasToken')))]" ] }, "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptCoherenceFile'), ' <<< \"', parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('adminVMName'),' ',variables('const_wlsHome'),' ',variables('const_wlsDomainPath'),' ', parameters('storageAccountName'), ' ', listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '${azure.apiVersion2}').keys[0].value,' ', variables('const_mountPointPath'),' ', parameters('enableCoherenceWebLocalStorage'),' ',parameters('elkSettings').enable, ' ',parameters('elkSettings').elasticsearchEndpoint,' ', parameters('elkSettings').elasticsearchUserName,' ', parameters('elkSettings').elasticsearchPassword, ' ', array.join(parameters('elkSettings').logsToIntegrate), ' ',parameters('elkSettings').logIndex, ' ',variables('name_wlsServerPrefix'),' ',copyIndex(variables('const_cacheServerIndexOffset')),' ',parameters('customSSLSettings').enable,' ',if(parameters('customSSLSettings').enable,base64(parameters('customSSLSettings').customIdentityKeyStoreBase64String), 'null'),' ',if(parameters('customSSLSettings').enable,base64(parameters('customSSLSettings').customIdentityKeyStorePassPhrase), 'null'),' ',if(parameters('customSSLSettings').enable,base64(parameters('customSSLSettings').customIdentityKeyStoreType), 'null'),' ',if(parameters('customSSLSettings').enable,base64(parameters('customSSLSettings').customTrustKeyStoreBase64String), 'null'),' ',if(parameters('customSSLSettings').enable,base64(parameters('customSSLSettings').customTrustKeyStorePassPhrase), 'null'),' ',if(parameters('customSSLSettings').enable,base64(parameters('customSSLSettings').customTrustKeyStoreType), 'null'),' ',if(parameters('customSSLSettings').enable,base64(parameters('customSSLSettings').privateKeyAlias), 'null'),' ',if(parameters('customSSLSettings').enable,base64(parameters('customSSLSettings').privateKeyPassPhrase), 'null'),'\"')]" + "commandToExecute": "[concat('sh',' ',variables('name_scriptCoherenceFile'), ' <<< \"', parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('adminVMName'),' ',variables('const_wlsHome'),' ',variables('const_wlsDomainPath'),' ', parameters('storageAccountName'), ' ', listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '${azure.apiVersionForStorage}').keys[0].value,' ', variables('const_mountPointPath'),' ', parameters('enableCoherenceWebLocalStorage'),' ',parameters('elkSettings').enable, ' ',parameters('elkSettings').elasticsearchEndpoint,' ', parameters('elkSettings').elasticsearchUserName,' ', parameters('elkSettings').elasticsearchPassword, ' ', array.join(parameters('elkSettings').logsToIntegrate), ' ',parameters('elkSettings').logIndex, ' ',variables('name_wlsServerPrefix'),' ',copyIndex(variables('const_cacheServerIndexOffset')),' ',if(parameters('enableDNSConfiguration'),parameters('customDNSNameForAdminServer'),parameters('adminVMName')),' ',parameters('dnsLabelPrefix'),' ',parameters('location'),' ','True',' ',parameters('customSSLSettings').enable,' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customIdentityKeyStoreBase64String, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customIdentityKeyStorePassPhrase, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customIdentityKeyStoreType, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customTrustKeyStoreBase64String, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customTrustKeyStorePassPhrase, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customTrustKeyStoreType, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').privateKeyAlias, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').privateKeyPassPhrase, 'null'),'\"')]" } } }, { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${cluster.addnode.coherence.end}", "type": "Microsoft.Resources/deployments", "dependsOn": [ @@ -422,4 +465,4 @@ "value": "[parameters('_artifactsLocation')]" } } -} \ No newline at end of file +} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode/pom.xml b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode/pom.xml index 9cca61cbd..02b157da1 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode/pom.xml +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode/pom.xml @@ -1,38 +1,39 @@ - + 4.0.0 - com.oracle.weblogic.azure - arm-oraclelinux-wls-cluster-addnode - 1.0.24 - - com.microsoft.azure.iaas - azure-javaee-iaas-parent - 1.0.7 - + com.oracle.weblogic.azure + weblogic-azure-vm + 1.0.0 + ../../pom.xml - + + com.oracle.weblogic.azure + arm-oraclelinux-wls-cluster-addnode + ${version.arm-oraclelinux-wls-cluster-addnode} + jar ${project.artifactId} - ${basedir}/../../arm-ttk/arm-ttk - -TestParameter '@{"SampleName"="addnode/src/main";"RawRepoPath"="${artifactsLocationBase}/arm-oraclelinux-wls-cluster/${git.tag}/"}' - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/pid.properties - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/microsoft-pid.properties + -TestParameter '@{"SampleName"="addnode/src/main";"RawRepoPath"="${artifactsLocationBase}/arm-oraclelinux-wls-cluster/"}' + ${project.basedir}/../../.. + false + false - + diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode/src/main/arm/addnodedeploy.parameters.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode/src/main/arm/addnodedeploy.parameters.json index f2e547937..9db481610 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode/src/main/arm/addnodedeploy.parameters.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode/src/main/arm/addnodedeploy.parameters.json @@ -19,6 +19,9 @@ "adminURL": { "value": "GEN-UNIQUE" }, + "adminVMName": { + "value": "GEN-UNIQUE" + }, "adminUsername": { "value": "GEN-UNIQUE" }, @@ -54,7 +57,7 @@ "usePreviewImage": { "value": "GEN-UNIQUE" }, - "vmSizeSelect": { + "vmSize": { "value": "GEN-UNIQUE" }, "wlsDomainName": { @@ -66,6 +69,12 @@ "wlsPassword": { "value": "GEN-UNIQUE" }, + "enableDNSConfiguration": { + "value": false + }, + "customDNSNameForAdminServer" : { + "value": "GEN-UNIQUE" + }, "customSSLSettings": { "value": { "enable": false, diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode/src/main/arm/mainTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode/src/main/arm/mainTemplate.json index 278585185..be5a0898e 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode/src/main/arm/mainTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode/src/main/arm/mainTemplate.json @@ -7,7 +7,7 @@ "metadata": { "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." }, - "defaultValue": "${artifactsLocationBase}/arm-oraclelinux-wls-cluster/${git.tag}/addnode/src/main/" + "defaultValue": "${artifactsLocationBase}/arm-oraclelinux-wls-cluster/addnode/src/main/" }, "_artifactsLocationSasToken": { "type": "securestring", @@ -40,6 +40,13 @@ "description": "Provide admin URL with vm0_public_ip:7001" } }, + "adminVMName": { + "type": "string", + "defaultValue": "adminVM", + "metadata": { + "description": "Provide admin VM Name ex: adminVM" + } + }, "adminUsername": { "type": "string", "defaultValue": "weblogic", @@ -135,13 +142,23 @@ }, "skuUrnVersion": { "type": "string", - "defaultValue": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "defaultValue": "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", "allowedValues": [ - "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest", - "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest", + "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", + "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest", + "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest", + "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest", + "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest", + "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest", "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest", "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest", - "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" + "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest", + "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel76;Oracle:weblogic-122140-jdk8-rhel76:owls-122140-jdk8-rhel76;latest", + "owls-141100-jdk8-rhel76;Oracle:weblogic-141100-jdk8-rhel76:owls-141100-jdk8-rhel76;latest", + "owls-141100-jdk11-rhel76;Oracle:weblogic-141100-jdk11-rhel76:owls-141100-jdk11-rhel76;latest" ], "metadata": { "description": "The Oracle Linux image with Weblogic and Java preinstalled. Semicolon separated string of Sku, URN, and Version" @@ -160,13 +177,34 @@ "description": "Bool value, if it's set to true, will deploy with preview weblogic image." } }, - "vmSizeSelect": { + "vmSize": { "type": "string", "defaultValue": "Standard_A3", "metadata": { "description": "Select appropriate VM Size as per requirement" } }, + "virtualNetworkName": { + "type": "string", + "defaultValue": "wls-vnet", + "metadata": { + "description": "Name of the existing or new VNET" + } + }, + "virtualNetworkResourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "Resource group of Virtual network" + } + }, + "subnetName": { + "type": "string", + "defaultValue": "wls-subnet", + "metadata": { + "description": "Name of the existing or new Subnet" + } + }, "wlsDomainName": { "type": "string", "defaultValue": "wlsd", @@ -186,6 +224,20 @@ "description": "Password for your Weblogic domain name" } }, + "enableDNSConfiguration": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "Boolean value indicating, if DNS Zone Configuration is enabled or not" + } + }, + "customDNSNameForAdminServer": { + "type": "string", + "defaultValue": "none", + "metadata": { + "description": "Custom DNS Name for WebLogic Admin Server" + } + }, "customSSLSettings": { "type": "secureObject", "defaultValue": { @@ -225,7 +277,7 @@ }, "const_mountPointPath": "[concat('/mnt/', variables('name_share'))]", "const_publicIPAddressType": "Dynamic", - "const_vmSize": "[parameters('vmSizeSelect')]", + "const_vmSize": "[parameters('vmSize')]", "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", "const_wlsDomainPath": "/u01/domains", "name_appGateway": "myAppGateway", @@ -247,8 +299,8 @@ "name_scriptELKConfiguration": "elkIntegration.sh", "name_scriptFile": "addnode.sh", "name_share": "wlsshare", - "name_subnet": "Subnet", - "name_virtualNetwork": "[concat(parameters('wlsDomainName'),'_VNET')]", + "name_subnet": "[parameters('subnetName')]", + "name_virtualNetwork": "[parameters('virtualNetworkName')]", "name_vmMachine": "[concat(parameters('managedServerPrefix'),'VM')]", "ref_backendAddressPool": "[resourceId('Microsoft.Network/applicationGateways/backendAddressPools', variables('name_appGateway'),variables('name_backendAddressPool'))]", "ref_backendHttpSettings": "[resourceId('Microsoft.Network/applicationGateways/backendHttpSettingsCollection', variables('name_appGateway'),variables('name_httpSetting'))]", @@ -259,7 +311,11 @@ "ref_httpListener": "[resourceId('Microsoft.Network/applicationGateways/httpListeners', variables('name_appGateway'),variables('name_httpListener'))]", "ref_httpsListener": "[resourceId('Microsoft.Network/applicationGateways/httpListeners', variables('name_appGateway'),variables('name_httpsListener'))]", "ref_sslCertificate": "[resourceId('Microsoft.Network/applicationGateways/sslCertificates', variables('name_appGateway'),variables('name_appGatewayCertificate'))]", - "ref_subnet": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]" + "ref_subnet": "[resourceId(parameters('virtualNetworkResourceGroupName'), 'Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]", + "name_customHostnameGeneratorscriptFile": "generateCustomHostNameVerifier.sh", + "name_customHostnameVerifierJavaFile": "src/main/java/WebLogicCustomHostNameVerifier.java", + "name_customHostnameValuesTemplate": "src/main/java/HostNameValuesTemplate.txt", + "name_customHostnameVerifierTest" : "src/test/java/WebLogicCustomHostNameVerifierTest.java" }, "functions": [ { @@ -283,7 +339,7 @@ "resources": [ { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${cluster.addnode.start}", "properties": { "mode": "Incremental", @@ -295,8 +351,8 @@ } }, { + "apiVersion": "${azure.apiVersionForPublicIPAddresses}", "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_vmMachine'),copyIndex(variables('const_appNodeMachineOffset')),variables('name_publicIPAddress'))]", "location": "[parameters('location')]", "copy": { @@ -311,14 +367,14 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualNetworks}", "type": "Microsoft.Network/virtualNetworks/subnets", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_virtualNetwork'), '/', variables('name_subnet'))]", "condition": "[and(empty(variables('name_virtualNetwork')), empty(variables('name_subnet')))]" }, { + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_vmMachine'),copyIndex(variables('const_appNodeMachineOffset')), variables('name_nic'))]", "location": "[parameters('location')]", "copy": { @@ -349,8 +405,8 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_vmMachine'), copyIndex(variables('const_appNodeMachineOffset')))]", "location": "[parameters('location')]", "copy": { @@ -385,17 +441,7 @@ "managedDisk": { "storageAccountType": "Standard_LRS" } - }, - "dataDisks": [ - { - "lun": 0, - "createOption": "FromImage", - "diskSizeGB": 900, - "managedDisk": { - "storageAccountType": "Standard_LRS" - } - } - ] + } }, "networkProfile": { "networkInterfaces": [ @@ -407,7 +453,7 @@ "diagnosticsProfile": { "bootDiagnostics": { "enabled": true, - "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', parameters('storageAccountName')), '${azure.apiVersion2}').primaryEndpoints.blob]" + "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', parameters('storageAccountName')), '${azure.apiVersionForStorage}').primaryEndpoints.blob]" } } }, @@ -419,7 +465,7 @@ }, { "type": "Microsoft.Network/applicationGateways", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForApplicationGateways}", "condition": "[parameters('appGatewaySettings').enable]", "name": "[variables('name_appGateway')]", "location": "[parameters('location')]", @@ -552,6 +598,7 @@ "name": "HTTPRoutingRule", "properties": { "ruleType": "Basic", + "priority": 1000, "httpListener": { "id": "[variables('ref_httpListener')]" }, @@ -568,6 +615,7 @@ "name": "HTTPSRoutingRule", "properties": { "ruleType": "Basic", + "priority": 1001, "httpListener": { "id": "[variables('ref_httpsListener')]" }, @@ -609,8 +657,8 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_vmMachine'), copyIndex(variables('const_appNodeMachineOffset')), '/newuserscript')]", "location": "[parameters('location')]", "copy": { @@ -628,16 +676,21 @@ "settings": { "fileUris": [ "[uri(parameters('_artifactsLocation'), concat('scripts/', variables('name_scriptFile'), parameters('_artifactsLocationSasToken')))]", - "[uri(parameters('_artifactsLocation'), concat('../../../arm-oraclelinux-wls-cluster/src/main/scripts/', variables('name_scriptELKConfiguration'), parameters('_artifactsLocationSasToken')))]" + "[uri(parameters('_artifactsLocation'), concat('../../../arm-oraclelinux-wls-cluster/src/main/scripts/', variables('name_scriptELKConfiguration'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameGeneratorscriptFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierJavaFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameValuesTemplate'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierTest'), parameters('_artifactsLocationSasToken')))]" + ] }, "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'),' <<< \"',parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('managedServerPrefix'),' ', copyIndex(variables('const_appNodeMachineOffset')),' ', parameters('adminURL'),' ',variables('const_wlsHome'),' ',variables('const_wlsDomainPath'),' ',parameters('storageAccountName'), ' ', listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '${azure.apiVersion2}').keys[0].value,' ', variables('const_mountPointPath'),' ', if(parameters('aadsSettings').enable, parameters('aadsSettings').certificateBase64String, 'null'),' ',if(parameters('aadsSettings').enable, parameters('aadsSettings').publicIP, 'null'),' ', if(parameters('aadsSettings').enable, parameters('aadsSettings').serverHost, 'null'),' ',if(parameters('appGatewaySettings').enable, reference(resourceId('Microsoft.Network/publicIPAddresses', parameters('appGatewaySettings').publicIPName),'${azure.apiVersion}').dnsSettings.fqdn, 'null'), ' ',parameters('elkSettings').enable, ' ',parameters('elkSettings').elasticsearchEndpoint,' ', parameters('elkSettings').elasticsearchUserName,' ', parameters('elkSettings').elasticsearchPassword, ' ', array.join(parameters('elkSettings').logsToIntegrate), ' ',parameters('elkSettings').logIndex, ' ', parameters('enableCoherence'),' ',parameters('customSSLSettings').enable,' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customIdentityKeyStoreBase64String, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customIdentityKeyStorePassPhrase, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customIdentityKeyStoreType, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customTrustKeyStoreBase64String, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customTrustKeyStorePassPhrase, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customTrustKeyStoreType, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').privateKeyAlias, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').privateKeyPassPhrase, 'null'),'\"')]" } + "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'),' <<< \"',parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('managedServerPrefix'),' ', copyIndex(variables('const_appNodeMachineOffset')),' ', parameters('adminURL'),' ',parameters('adminVMName'),' ',variables('const_wlsHome'),' ',variables('const_wlsDomainPath'),' ',parameters('storageAccountName'), ' ', listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '${azure.apiVersionForStorage}').keys[0].value,' ', variables('const_mountPointPath'),' ', if(parameters('aadsSettings').enable, parameters('aadsSettings').certificateBase64String, 'null'),' ',if(parameters('aadsSettings').enable, parameters('aadsSettings').publicIP, 'null'),' ', if(parameters('aadsSettings').enable, parameters('aadsSettings').serverHost, 'null'),' ',if(parameters('appGatewaySettings').enable, reference(resourceId('Microsoft.Network/publicIPAddresses', parameters('appGatewaySettings').publicIPName),'${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn, 'null'), ' ',parameters('elkSettings').enable, ' ',parameters('elkSettings').elasticsearchEndpoint,' ', parameters('elkSettings').elasticsearchUserName,' ', parameters('elkSettings').elasticsearchPassword, ' ', array.join(parameters('elkSettings').logsToIntegrate), ' ',parameters('elkSettings').logIndex, ' ', parameters('enableCoherence'),' ',if(parameters('enableDNSConfiguration'),parameters('customDNSNameForAdminServer'),parameters('adminVMName')),' ',parameters('dnsLabelPrefix'),' ',parameters('location'),' ',parameters('customSSLSettings').enable,' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customIdentityKeyStoreBase64String, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customIdentityKeyStorePassPhrase, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customIdentityKeyStoreType, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customTrustKeyStoreBase64String, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customTrustKeyStorePassPhrase, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customTrustKeyStoreType, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').privateKeyAlias, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').privateKeyPassPhrase, 'null'),'\"')]" } } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${cluster.addnode.end}", "dependsOn": [ "virtualMachineExtensionLoop" diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode/src/main/scripts/addnode.sh b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode/src/main/scripts/addnode.sh index fcd0524d5..794a2a864 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode/src/main/scripts/addnode.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/addnode/src/main/scripts/addnode.sh @@ -46,9 +46,9 @@ function validateInput() echo_stderr "wlsDomainName is required. " fi - if [[ -z "$wlsUserName" || -z "$wlsPassword" ]] + if [[ -z "$wlsUserName" || -z "$wlsShibboleth" ]] then - echo_stderr "wlsUserName or wlsPassword is required. " + echo_stderr "Weblogic username or password is required. " exit 1 fi @@ -145,7 +145,7 @@ function validateInput() echo_stderr "enableCoherence is required. " fi - if [ ! -z "$isCustomSSLEnabled" == "true" ]; + if [ "${isCustomSSLEnabled}" == "true" ]; then if [[ -z "$customIdentityKeyStoreBase64String" || -z "$customIdentityKeyStorePassPhrase" || -z "$customIdentityKeyStoreType" || -z "$customTrustKeyStoreBase64String" || -z "$customTrustKeyStorePassPhrase" || -z "$customTrustKeyStoreType" || @@ -165,6 +165,7 @@ function cleanup() rm -rf $wlsDomainPath/weblogic-deploy.zip rm -rf $wlsDomainPath/weblogic-deploy rm -rf $wlsDomainPath/*.py + rm -rf ${CUSTOM_HOSTNAME_VERIFIER_HOME} echo "Cleanup completed." } @@ -175,7 +176,7 @@ function create_managed_model() cat <$wlsDomainPath/managed-domain.yaml domainInfo: AdminUserName: "$wlsUserName" - AdminPassword: "$wlsPassword" + AdminPassword: "$wlsShibboleth" ServerStartMode: prod topology: Name: "$wlsDomainName" @@ -194,9 +195,11 @@ topology: Notes: "$wlsServerName managed server" Cluster: "$wlsClusterName" Machine: "$nmHost" + ServerStart: + Arguments: '${SERVER_STARTUP_ARGS}' SecurityConfiguration: NodeManagerUsername: "$wlsUserName" - NodeManagerPasswordEncrypted: "$wlsPassword" + NodeManagerPasswordEncrypted: "$wlsShibboleth" EOF } @@ -205,7 +208,7 @@ function create_machine_model() { echo "Creating machine name model for managed server $wlsServerName" cat <$wlsDomainPath/add-machine.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') edit("$wlsServerName") startEdit() cd('/') @@ -231,7 +234,7 @@ function create_ms_server_model() isCustomSSLEnabled='${isCustomSSLEnabled}' -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') edit("$wlsServerName") startEdit() cd('/') @@ -255,12 +258,15 @@ if isCustomSSLEnabled == 'true' : cd('/Servers/$wlsServerName/SSL/$wlsServerName') cmo.setServerPrivateKeyAlias('$privateKeyAlias') set('ServerPrivateKeyPassPhrase', '$privateKeyPassPhrase') - cmo.setHostnameVerificationIgnored(true) cd('/Servers/$wlsServerName/ServerStart/$wlsServerName') -arguments = '-Dweblogic.Name=$wlsServerName -Dweblogic.security.SSL.ignoreHostnameVerification=true' -cmo.setArguments(arguments) - +arguments = '${SERVER_STARTUP_ARGS} -Dweblogic.Name=$wlsServerName ' +oldArgs = cmo.getArguments() +if oldArgs != None: + newArgs = oldArgs + ' ' + arguments +else: + newArgs = arguments +cmo.setArguments(newArgs) EOF if [ "$appGWHostName" != "null" ]; then @@ -294,7 +300,8 @@ EOF if [ "${enableAAD}" == "true" ]; then cat <>$wlsDomainPath/add-server.py -cmo.setHostnameVerificationIgnored(true) +#need to revisit this as HostNameVerification is not supported +#cmo.setHostnameVerificationIgnored(true) EOF fi @@ -334,7 +341,12 @@ EOF cat <>$wlsDomainPath/add-server.py cd('/Servers/$wlsServerName//ServerStart/$wlsServerName') -cmo.setArguments(arguments) +oldArgs = cmo.getArguments() +if oldArgs != None: + newArgs = oldArgs + ' ' + arguments +else: + newArgs = arguments +cmo.setArguments(newArgs) save() resolve() activate() @@ -407,7 +419,8 @@ Description=WebLogic nodemanager service Type=simple # Note that the following three parameters should be changed to the correct paths # on your own system -WorkingDirectory="$wlsDomainPath/$wlsDomainName" +WorkingDirectory=$wlsDomainPath/$wlsDomainName +Environment="JAVA_OPTIONS=${SERVER_STARTUP_ARGS}" ExecStart="$wlsDomainPath/$wlsDomainName/bin/startNodeManager.sh" ExecStop="$wlsDomainPath/$wlsDomainName/bin/stopNodeManager.sh" User=oracle @@ -425,7 +438,7 @@ function start_managed() { echo "Starting managed server $wlsServerName" cat <$wlsDomainPath/start-server.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') try: start('$wlsServerName', 'Server') except: @@ -552,8 +565,8 @@ function mountFileShare() fi echo "chmod 600 /etc/smbcredentials/${storageAccountName}.cred" sudo chmod 600 /etc/smbcredentials/${storageAccountName}.cred - echo "//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred ,dir_mode=0777,file_mode=0777,serverino" - sudo bash -c "echo \"//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred ,dir_mode=0777,file_mode=0777,serverino\" >> /etc/fstab" + echo "//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino" + sudo bash -c "echo \"//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino\" >> /etc/fstab" echo "mount -t cifs //${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino" sudo mount -t cifs //${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino if [[ $? != 0 ]]; @@ -609,7 +622,7 @@ function importAADCertificate() { # import the key to java security . $oracleHome/oracle_common/common/bin/setWlstEnv.sh - # For AAD failure: exception happens when importing certificate to JDK 11.0.7 + # For Entra ID failure: exception happens when importing certificate to JDK 11.0.7 # ISSUE: https://github.com/wls-eng/arm-oraclelinux-wls/issues/109 # JRE was removed since JDK 11. java_version=$(java -version 2>&1 | sed -n ';s/.* version "\(.*\)\.\(.*\)\..*"/\1\2/p;') @@ -645,14 +658,14 @@ function importAADCertificateIntoWLSCustomTrustKeyStore() exit 1 fi - # For SSL enabled causes AAD failure #225 + # For SSL enabled causes Entra ID failure #225 # ISSUE: https://github.com/wls-eng/arm-oraclelinux-wls/issues/225 - echo "Importing AAD Certificate into WLS Custom Trust Key Store: " + echo "Importing Entra ID Certificate into WLS Custom Trust Key Store: " sudo ${JAVA_HOME}/bin/keytool -noprompt -import -trustcacerts -keystore {KEYSTORE_PATH}/trust.keystore -storepass ${customTrustKeyStorePassPhrase} -alias aadtrust -file ${addsCertificate} -storetype ${customTrustKeyStoreType} else - echo "customSSL not enabled. Not required to configure AAD for WebLogic Custom SSL" + echo "customSSL not enabled. Not required to configure Entra ID for WebLogic Custom SSL" fi } @@ -689,6 +702,7 @@ function parseAndSaveCustomSSLKeyStoreData() echo "$customIdentityKeyStoreBase64String" > ${KEYSTORE_PATH}/identityKeyStoreCerBase64String.txt cat ${KEYSTORE_PATH}/identityKeyStoreCerBase64String.txt | base64 -d > ${KEYSTORE_PATH}/identity.keystore customSSLIdentityKeyStoreFile=${KEYSTORE_PATH}/identity.keystore + customIdentityKeyStorePassPhrase="$(echo $customIdentityKeyStorePassPhrase | base64 --decode)" rm -rf ${KEYSTORE_PATH}/identityKeyStoreCerBase64String.txt @@ -698,19 +712,82 @@ function parseAndSaveCustomSSLKeyStoreData() echo "$customTrustKeyStoreBase64String" > ${KEYSTORE_PATH}/trustKeyStoreCerBase64String.txt cat ${KEYSTORE_PATH}/trustKeyStoreCerBase64String.txt | base64 -d > ${KEYSTORE_PATH}/trust.keystore customSSLTrustKeyStoreFile=${KEYSTORE_PATH}/trust.keystore + customTrustKeyStorePassPhrase="$(echo $customTrustKeyStorePassPhrase | base64 --decode)" rm -rf ${KEYSTORE_PATH}/trustKeyStoreCerBase64String.txt + privateKeyAlias="$(echo $privateKeyAlias | base64 --decode)" + privateKeyPassPhrase="$(echo $privateKeyPassPhrase | base64 --decode)" + validateSSLKeyStores } +function generateCustomHostNameVerifier() +{ + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME} + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/test/java + cp ${BASE_DIR}/generateCustomHostNameVerifier.sh ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh + cp ${BASE_DIR}/WebLogicCustomHostNameVerifier.java ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java/WebLogicCustomHostNameVerifier.java + cp ${BASE_DIR}/HostNameValuesTemplate.txt ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java/HostNameValuesTemplate.txt + cp ${BASE_DIR}/WebLogicCustomHostNameVerifierTest.java ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/test/java/WebLogicCustomHostNameVerifierTest.java + chown -R $username:$groupname ${CUSTOM_HOSTNAME_VERIFIER_HOME} + chmod +x ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh + + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh ${wlsAdminHost} ${customDNSNameForAdminServer} ${customDNSNameForAdminServer} ${dnsLabelPrefix} ${wlsDomainName} ${location}" +} + +function copyCustomHostNameVerifierJarsToWebLogicClasspath() +{ + runuser -l oracle -c "cp ${CUSTOM_HOSTNAME_VERIFIER_HOME}/output/*.jar $oracleHome/wlserver/server/lib/;" + + echo "Modify WLS CLASSPATH to include hostname verifier jars...." + sed -i 's;^WEBLOGIC_CLASSPATH="${WL_HOME}/server/lib/postgresql.*;&\nWEBLOGIC_CLASSPATH="${WL_HOME}/server/lib/hostnamevalues.jar:${WL_HOME}/server/lib/weblogicustomhostnameverifier.jar:${WEBLOGIC_CLASSPATH}";' $oracleHome/oracle_common/common/bin/commExtEnv.sh + echo "Modified WLS CLASSPATH to include hostname verifier jars." +} + + +function configureCustomHostNameVerifier() +{ + echo "configureCustomHostNameVerifier for domain $wlsDomainName for server $wlsServerName" + cat <${wlsDomainPath}/configureCustomHostNameVerifier.py +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') +try: + edit("$wlsServerName") + startEdit() + + cd('/Servers/$wlsServerName/SSL/$wlsServerName') + cmo.setHostnameVerifier('com.oracle.azure.weblogic.security.util.WebLogicCustomHostNameVerifier') + cmo.setHostnameVerificationIgnored(false) + cmo.setTwoWaySSLEnabled(false) + cmo.setClientCertificateEnforced(false) + + save() + activate() +except Exception,e: + print e + print "Failed to configureCustomHostNameVerifier for domain $wlsDomainName" + dumpStack() + raise Exception('Failed to configureCustomHostNameVerifier for domain $wlsDomainName') +disconnect() +EOF +sudo chown -R $username:$groupname ${wlsDomainPath} +runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST ${wlsDomainPath}/configureCustomHostNameVerifier.py" +if [[ $? != 0 ]]; then + echo "Error : Failed to configureCustomHostNameVerifier for domain $wlsDomainName" + exit 1 +fi + +} #main script starts here SCRIPT_PWD=`pwd` +CURR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +BASE_DIR="$(readlink -f ${CURR_DIR})" #read arguments from stdin -read wlsDomainName wlsUserName wlsPassword managedServerPrefix serverIndex wlsAdminURL oracleHome wlsDomainPath storageAccountName storageAccountKey mountpointPath wlsADSSLCer wlsLDAPPublicIP adServerHost appGWHostName enableELK elasticURI elasticUserName elasticPassword logsToIntegrate logIndex enableCoherence isCustomSSLEnabled customIdentityKeyStoreBase64String customIdentityKeyStorePassPhrase customIdentityKeyStoreType customTrustKeyStoreBase64String customTrustKeyStorePassPhrase customTrustKeyStoreType privateKeyAlias privateKeyPassPhrase +read wlsDomainName wlsUserName wlsShibboleth managedServerPrefix serverIndex wlsAdminURL wlsAdminHost oracleHome wlsDomainPath storageAccountName storageAccountKey mountpointPath wlsADSSLCer wlsLDAPPublicIP adServerHost appGWHostName enableELK elasticURI elasticUserName elasticPassword logsToIntegrate logIndex enableCoherence customDNSNameForAdminServer dnsLabelPrefix location isCustomSSLEnabled customIdentityKeyStoreBase64String customIdentityKeyStorePassPhrase customIdentityKeyStoreType customTrustKeyStoreBase64String customTrustKeyStorePassPhrase customTrustKeyStoreType privateKeyAlias privateKeyPassPhrase isCustomSSLEnabled="${isCustomSSLEnabled,,}" @@ -730,8 +807,9 @@ AppGWHttpsPort=443 WEBLOGIC_DEPLOY_TOOL=https://github.com/oracle/weblogic-deploy-tooling/releases/download/weblogic-deploy-tooling-1.8.1/weblogic-deploy.zip username="oracle" groupname="oracle" - +CUSTOM_HOSTNAME_VERIFIER_HOME="/u01/app/custom-hostname-verifier" KEYSTORE_PATH="$wlsDomainPath/$wlsDomainName/keystores" +SERVER_STARTUP_ARGS="-Dlog4j2.formatMsgNoLookups=true" chmod ugo+x ${SCRIPT_PWD}/elkIntegration.sh @@ -753,8 +831,11 @@ if [ "$enableAAD" == "true" ];then fi create_managedSetup +generateCustomHostNameVerifier +copyCustomHostNameVerifierJarsToWebLogicClasspath create_nodemanager_service enabledAndStartNodeManagerService +configureCustomHostNameVerifier start_managed echo "enable ELK? ${enableELK}" @@ -764,7 +845,7 @@ if [[ "${enableELK,,}" == "true" ]];then ${oracleHome} \ ${wlsAdminURL} \ ${wlsUserName} \ - ${wlsPassword} \ + ${wlsShibboleth} \ "admin" \ ${elasticURI} \ ${elasticUserName} \ diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/pom.xml b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/pom.xml index cec4636f0..3b068084c 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/pom.xml +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/pom.xml @@ -1,38 +1,38 @@ - + 4.0.0 - com.oracle.weblogic.azure - arm-oraclelinux-wls-cluster - 1.0.370000 - - com.microsoft.azure.iaas - azure-javaee-iaas-parent - 1.0.7 - + com.oracle.weblogic.azure + weblogic-azure-vm + 1.0.0 + ../../pom.xml - + + com.oracle.weblogic.azure + arm-oraclelinux-wls-cluster + ${version.arm-oraclelinux-wls-cluster} + jar ${project.artifactId} - ${basedir}/../../arm-ttk/arm-ttk - -TestParameter '@{"PasswordMinLength"=5}' - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/pid.properties - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/microsoft-pid.properties + ${project.basedir}/../../.. + false + false - + - + diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/clusterdeploy.parameters.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/clusterdeploy.parameters.json index f967153af..44995e9ec 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/clusterdeploy.parameters.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/clusterdeploy.parameters.json @@ -4,22 +4,121 @@ "parameters": { "adminUsername": { "value": "GEN-UNIQUE" - }, + }, "adminPasswordOrKey": { "value": "GEN-SSH-PUB-KEY" }, + "adminVMName":{ + "value": "GEN-UNIQUE" + }, + "appGatewayCertificateOption":{ + "value": "GEN-UNIQUE" + }, + "appGatewaySSLBackendCertData":{ + "value": "GEN-UNIQUE" + }, + "appGatewaySSLCertData":{ + "value": "GEN-UNIQUE" + }, + "appGatewaySSLCertPassword":{ + "value": "GEN-UNIQUE" + }, + "authenticationType": { + "value": "password" + }, + "databaseType": { + "value": "mysql" + }, + "dbGlobalTranProperty": { + "value": "OnePhaseCommit" + }, + "dbIdentity": { + "value": {} + }, + "dbPassword": { + "value": "GEN-UNIQUE" + }, + "dbUser": { + "value": "GEN-UNIQUE" + }, + "denyPublicTrafficForManagedServer": { + "value": false + }, + "dsConnectionURL": { + "value": "GEN-UNIQUE" + }, "dnsLabelPrefix": { "value": "GEN-UNIQUE" }, - "acceptOTNLicenseAgreement": { + "dnsNameforApplicationGateway":{ "value": "GEN-UNIQUE" }, - "otnAccountUsername": { + "dnszoneName": { "value": "GEN-UNIQUE" }, - "otnAccountPassword": { + "dnszoneResourceGroup": { + "value": "GEN-UNIQUE" + }, + "dnszoneAdminConsoleLabel": { + "value": "GEN-UNIQUE" + }, + "dnszoneAppGatewayLabel": { + "value": "GEN-UNIQUE" + }, + "enableAppGateway": { + "value": false + }, + "enableCoherence": { + "value": false + }, + "enableCoherenceWebLocalStorage": { + "value": false + }, + "enableCookieBasedAffinity": { + "value": false + }, + "enableDB": { + "value": false + }, + "enableDNSConfiguration": { + "value": false + }, + "enableHTTPAdminListenPort": { + "value": false + }, + "enablePswlessConnection": { + "value": false + }, + "gatewayPublicIPAddressName": { "value": "GEN-UNIQUE" }, + "hasDNSZones": { + "value": false + }, + "jdbcDataSourceName": { + "value": "GEN-UNIQUE" + }, + "keyVaultSku": { + "value": "standard" + }, + "location": { + "value": "eastus" + }, + "portsToExpose": { + "value": "GEN-UNIQUE" + }, + "skuUrnVersion": { + "value": "GEN-UNIQUE" + }, + "tagsByResource": { + "value": {} + }, + "usePreviewImage": { + "value": false + }, + "useSystemAssignedManagedIdentity": { + "value": false + }, "wlsDomainName": { "value": "GEN-UNIQUE" }, @@ -32,20 +131,68 @@ "managedServerPrefix":{ "value": "GEN-UNIQUE" }, - "vmSizeSelect":{ + "virtualNetworkNewOrExisting": { + "value": "new" + }, + "virtualNetworkName": { + "value": "GEN-UNIQUE" + }, + "virtualNetworkResourceGroupName": { + "value": "GEN-UNIQUE" + }, + "addressPrefixes": { + "value": "10.0.0.0/16" + }, + "subnetName": { + "value": "GEN-UNIQUE" + }, + "subnetPrefix":{ + "value": "10.0.0.0/24" + }, + "subnetForAppGateway":{ + "value": "GEN-UNIQUE" + }, + "subnetPrefixForAppGateway":{ + "value": "10.0.1.0/24" + }, + "vmSize":{ + "value": "GEN-UNIQUE" + }, + "vmSizeSelectForCoherence":{ "value": "GEN-UNIQUE" }, "numberOfInstances": { "value": "GEN-UNIQUE" }, - "adminVMName": { - "value": "GEN-UNIQUE" - }, "denyPublicTrafficForAdminServer": { "value": false }, "enableCustomSSL": { "value": false + }, + "uploadedCustomIdentityKeyStoreData": { + "value": "GEN-UNIQUE" + }, + "uploadedCustomIdentityKeyStorePassphrase": { + "value": "GEN-UNIQUE" + }, + "uploadedCustomIdentityKeyStoreType": { + "value": "JKS" + }, + "uploadedCustomTrustKeyStoreData": { + "value": "GEN-UNIQUE" + }, + "uploadedCustomTrustKeyStorePassPhrase": { + "value": "GEN-UNIQUE" + }, + "uploadedCustomTrustKeyStoreType": { + "value": "JKS" + }, + "uploadedPrivateKeyAlias": { + "value": "GEN-UNIQUE" + }, + "uploadedPrivateKeyPassPhrase": { + "value": "GEN-UNIQUE" } } } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/createUiDefinition.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/createUiDefinition.json index 04977cbff..3b5d25087 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/createUiDefinition.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/createUiDefinition.json @@ -3,35 +3,74 @@ "handler": "Microsoft.Azure.CreateUIDef", "version": "0.1.2-preview", "parameters": { + "config": { + "basics": { + "resourceGroup": { + "allowExisting": true + } + } + }, "basics": [ { "name": "skuUrnVersion", "type": "Microsoft.Common.DropDown", "label": "Oracle WebLogic Image", - "defaultValue": "WebLogic Server 14.1.1.0.0 and JDK11 on Oracle Linux 7.6", + "defaultValue": "WebLogic Server 14.1.2.0.0 and JDK 21 on Oracle Linux 9", "toolTip": "Choose Oracle WebLogic image, which is provided by Oracle, with Java and WebLogic preinstalled.", "constraints": { "allowedValues": [ { - "label": "WebLogic Server 12.2.1.3.0 and JDK8 on Oracle Linux 7.4", - "value": "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest" + "label": "WebLogic Server 14.1.2.0.0 and JDK 21 on Oracle Linux 9", + "value": "owls-141200-jdk21-ol94;Oracle:weblogic-141200-jdk21-ol94:owls-141200-jdk21-ol94;latest" }, { - "label": "WebLogic Server 12.2.1.3.0 and JDK8 on Oracle Linux 7.3", - "value": "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest" + "label": "WebLogic Server 14.1.2.0.0 and JDK 21 on Oracle Linux 8", + "value": "owls-141200-jdk21-ol810;Oracle:weblogic-141200-jdk21-ol810:owls-141200-jdk21-ol810;latest" }, { - "label": "WebLogic Server 12.2.1.4.0 and JDK8 on Oracle Linux 7.6", - "value": "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest" + "label":"WebLogic Server 14.1.2.0.0 and JDK 17 on Oracle Linux 9", + "value": "owls-141200-jdk17-ol94;Oracle:weblogic-141200-jdk17-ol94:owls-141200-jdk17-ol94;latest" }, { - "label": "WebLogic Server 14.1.1.0.0 and JDK8 on Oracle Linux 7.6", - "value": "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest" + "label":"WebLogic Server 14.1.2.0.0 and JDK 17 on Oracle Linux 8", + "value": "owls-141200-jdk17-ol810;Oracle:weblogic-141200-jdk17-ol810:owls-141200-jdk17-ol810;latest" }, { - "label": "WebLogic Server 14.1.1.0.0 and JDK11 on Oracle Linux 7.6", - "value": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" - } + "label": "WebLogic Server 14.1.1.0.0 and JDK 11 on Oracle Linux 9", + "value": "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK 11 on Oracle Linux 8", + "value": "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK 8 on Oracle Linux 9", + "value": "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK 8 on Oracle Linux 8", + "value": "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest" + }, + { + "label": "WebLogic Server 12.2.1.4.0 and JDK 8 on Oracle Linux 9", + "value": "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest" + }, + { + "label": "WebLogic Server 12.2.1.4.0 and JDK 8 on Oracle Linux 8", + "value": "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK11 on Red Hat Enterprise Linux 8", + "value": "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK8 on Red Hat Enterprise Linux 8", + "value": "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest" + }, + { + "label": "WebLogic Server 12.2.1.4.0 and JDK8 on Red Hat Enterprise Linux 8", + "value": "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest" + } ], "required": true }, @@ -54,13 +93,23 @@ "Standard_B1ls", "Standard_A0", "Basic_A0", - "Standard_B1s" + "Standard_B1s", + ${azure.armBased.vmSize.list} ] }, "osPlatform": "Linux", "count": "1", "visible": true }, + { + "name": "invalidVMSizeInfo", + "type": "Microsoft.Common.InfoBox", + "visible": "[contains(basics('vmSizeSelect'),'p')]", + "options": { + "icon": "Error", + "text": "The VM size you selected includes the feature letter 'p', indicating it uses ARM CPUs. ARM platform is not supported. Please select a different VM size. For more information, refer to the Azure virtual machine sizes naming conventions." + } + }, { "name": "basicsRequired", "type": "Microsoft.Common.Section", @@ -74,8 +123,16 @@ "toolTip": "Use only letters and numbers", "constraints": { "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." + "validations": [ + { + "regex": "^[a-z0-9A-Z]{1,30}$", + "message": "The value must be 1-30 characters long and must only contain letters and numbers." + }, + { + "isValid": "[not(contains(basics('vmSizeSelect'),'p'))]", + "message": "ARM platform is not supported. Please select a different VM size." + } + ] }, "visible": true }, @@ -177,19 +234,6 @@ "required": true } }, - { - "name": "dnsLabelPrefix", - "type": "Microsoft.Common.TextBox", - "label": "DNS Label Prefix", - "toolTip": "The string to prepend to the DNS label.", - "defaultValue": "wls", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{3,10}$", - "validationMessage": "The prefix must be between 3 and 10 characters long and contain letters, numbers only." - }, - "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" - }, { "name": "managedServerPrefix", "type": "Microsoft.Common.TextBox", @@ -216,40 +260,6 @@ }, "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" }, - { - "name": "portsToExpose", - "label": "Ports and port ranges to expose (N or N-N, comma separated)", - "type": "Microsoft.Common.TextBox", - "toolTip": "Ports and port ranges to expose (N or N-N, comma separated)", - "defaultValue": "80,443,7001-9000", - "constraints": { - "required": true, - "regex": "^((([0-9]+-[0-9]+)|([0-9]+))[,]?)+[^,]$", - "validationMessage": "Only numbers, hyphen separated ranges of numbers, separated by commas" - }, - "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" - }, - { - "name": "denyPublicTrafficForAdminServer", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deny public traffic for admin server?", - "defaultValue": "No", - "toolTip": "Select 'Yes' to deny public traffic for admin server. Configuration here for port 7001 and 7002 has a higher priority than above.", - "constraints": { - "allowedValues": [ - { - "label": "No", - "value": false - }, - { - "label": "Yes", - "value": true - } - ], - "required": true - }, - "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" - }, { "name": "enableAdminHTTPListenPort", "type": "Microsoft.Common.OptionsGroup", @@ -291,15 +301,6 @@ }, "defaultValue": "Yes", "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" - }, - { - "name": "About", - "type": "Microsoft.Common.InfoBox", - "options": { - "icon": "None", - "text": "Template version ${project.version}" - }, - "visible": "[bool('${template.version.visible}')]" } ], "visible": true @@ -309,6 +310,18 @@ "type": "Microsoft.Common.Section", "label": "Report issues, get help, and share feedback", "elements": [ + { + "name": "help", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "See the documentation for this offer.", + "link": { + "label": "Offer documentation", + "uri": "https://aka.ms/wls-vm-docs" + } + } + }, { "name": "howToReportIssueText", "type": "Microsoft.Common.TextBlock", @@ -317,9 +330,9 @@ "text": "If you encounter problems during the deployment of Oracle WebLogic Server, report them here.", "link": { "label": "Issue tracker", - "uri": "https://aka.ms/arm-oraclelinux-wls-issues" + "uri": "https://aka.ms/arm-oraclelinux-wls-issues?version=${project.version}" } - } + } }, { "name": "howToJoinSlack", @@ -344,63 +357,44 @@ "uri": "https://aka.ms/wls-on-azure-survey" } } - } + } ], "visible": true - } + } ], "steps": [ -{ - "name": "section_sslConfiguration", - "type": "Microsoft.Common.Section", - "label": "TLS/SSL Configuration", - "elements": [{ - "name": "sslConfigurationText", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "Selecting 'Yes' here will cause the template to provision WebLogic Administration Console on HTTPS (Secure) port, with your own TLS/SSL Certificate.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-ssl-config" - } - } - }, - { - "name": "enableCustomSSL", - "type": "Microsoft.Common.OptionsGroup", - "label": "Configure WebLogic Administration Console on HTTPS (Secure) port, with your own TLS/SSL Certificate?", - "defaultValue": "No", - "toolTip": "Select 'Yes' to configure WebLogic Administration Console on HTTPS (Secure) port with your own SSL Certificate.", - "constraints": { - "allowedValues": [{ - "label": "Yes", - "value": true - }, - { - "label": "No", - "value": false - } - ], - "required": false - } - }, + { + "name": "section_sslConfiguration", + "type": "Microsoft.Common.Section", + "label": "TLS/SSL Configuration", + "elements": [ + { + "name": "sslConfigurationText", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "Selecting 'Yes' here will cause the template to provision WebLogic Administration Console on HTTPS (Secure) port, with your own TLS/SSL Certificate.", + "link": { + "label": "Learn more", + "uri": "https://aka.ms/arm-oraclelinux-wls-ssl-config" + } + } + }, { - "name": "sslConfigurationAccessOption", + "name": "enableCustomSSL", "type": "Microsoft.Common.OptionsGroup", - "visible": "[steps('section_sslConfiguration').enableCustomSSL]", - "label": "How would you like to provide required configuration", - "defaultValue": "Upload existing KeyStores", - "toolTip": "Select 'Upload existing KeyStores' to use local stored KeyStores.", + "label": "Configure WebLogic Administration Console on HTTPS (Secure) port, with your own TLS/SSL Certificate?", + "defaultValue": "No", + "toolTip": "Select 'Yes' to configure WebLogic Administration Console on HTTPS (Secure) port with your own SSL Certificate.", "constraints": { "allowedValues": [ { - "label": "Upload existing KeyStores", - "value": "uploadConfig" + "label": "Yes", + "value": true }, { - "label": "Use KeyStores stored in Azure Key Vault", - "value": "keyVaultStoredConfig" + "label": "No", + "value": false } ], "required": false @@ -409,7 +403,7 @@ { "name": "uploadedCustomSSLSettings", "type": "Microsoft.Common.Section", - "visible": "[and(steps('section_sslConfiguration').enableCustomSSL, equals(steps('section_sslConfiguration').sslConfigurationAccessOption, 'uploadConfig'))]", + "visible": "[steps('section_sslConfiguration').enableCustomSSL]", "label": "TLS/SSL Configuration Settings", "elements": [ { @@ -564,183 +558,9 @@ } } ] - }, - { - "name": "keyVaultStoredCustomSSLSettings", - "type": "Microsoft.Common.Section", - "visible": "[and(steps('section_sslConfiguration').enableCustomSSL, equals(steps('section_sslConfiguration').sslConfigurationAccessOption, 'keyVaultStoredConfig'))]", - "label": "TLS/SSL Configuration Settings", - "elements": [ - { - "name": "sslKeystoreInfo1", - "type": "Microsoft.Common.InfoBox", - "visible": "true", - "options": { - "icon": "Info", - "text": "You must provide different files for identity and trust KeyStores. Select here for more details.", - "uri": "https://aka.ms/arm-oraclelinux-wls-ssl-configuration" - } - }, - { - "name": "keyVaultText", - "type": "Microsoft.Common.TextBlock", - "visible": "true", - "options": { - "text": "Enabling a HTTPS (Secure) port for the Administration Console requires you to obtain a valid TLS/SSL Certificate. The template will look for the certificate and other configuration items in the Azure Key Vault specified here.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-cluster-app-gateway-key-vault" - } - } - }, - { - "name": "adminSSLKeyVaultResourceGroup", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "Resource group name in current subscription containing the Key Vault", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1})$", - "validationMessage": "[if(greater(length(steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.adminSSLKeyVaultResourceGroup), 90),'Resource group names only allow up to 90 characters.', 'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" - } - }, - { - "name": "adminSSLKeyVaultName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "Name of the Azure Key Vault containing secrets for the TLS/SSL Certificate", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^(?=.{3,24}$)[a-zA-Z](([a-z0-9A-Z]*|(?:\\-[^\\-][a-z0-9A-Z]*))*)$", - "validationMessage": "[if(or(greater(length(steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.adminSSLKeyVaultName), 24), less(length(steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.adminSSLKeyVaultName), 3)),'Vault name must be between 3-24 alphanumeric characters. The name must begin with a letter, end with a letter or digit, and not contain consecutive hyphens.','Vault name must only contain alphanumeric characters and dashes and cannot start with a number')]" - } - }, - { - "name": "keyVaultCustomIdentityKeyStoreDataSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the Identity KeyStore Data", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "keyVaultCustomIdentityKeyStorePassPhraseSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the passphrase for the Identity KeyStore", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "keyVaultCustomIdentityKeyStoreType", - "type": "Microsoft.Common.DropDown", - "visible": "true", - "label": "The Identity KeyStore type (JKS,PKCS12)", - "defaultValue": "JKS", - "toolTip": "One of the supported KeyStore types", - "constraints": { - "allowedValues": [{ - "label": "JKS", - "value": "JKS" - }, - { - "label": "PKCS12", - "value": "PKCS12" - } - ], - "required": true - } - }, - { - "name": "keyVaultPrivateKeyAliasSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the Private Key Alias", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "keyVaultPrivateKeyPassPhraseSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the passphrase for the Private Key", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "keyVaultCustomTrustKeyStoreDataSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the Trust KeyStore Data", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "keyVaultCustomTrustKeyStorePassPhraseSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the passphrase for the Trust KeyStore", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "keyVaultCustomTrustKeyStoreType", - "type": "Microsoft.Common.DropDown", - "visible": "true", - "label": "The Trust KeyStore type (JKS,PKCS12)", - "defaultValue": "JKS", - "toolTip": "One of the supported KeyStore types", - "constraints": { - "allowedValues": [{ - "label": "JKS", - "value": "JKS" - }, - { - "label": "PKCS12", - "value": "PKCS12" - } - ], - "required": true - } - } - ] - } - ] - }, + } + ] + }, { "name": "section_appGateway", "type": "Microsoft.Common.Section", @@ -779,7 +599,15 @@ } }, { - "name": "keyVaultText00", + "name": "enableCookieBasedAffinity", + "type": "Microsoft.Common.CheckBox", + "label": "Enable cookie based affinity", + "defaultValue": "true", + "toolTip": "If checked, enable cookie based affinity", + "visible": "[steps('section_appGateway').enableAppGateway]" + }, + { + "name": "sslText00", "type": "Microsoft.Common.TextBlock", "visible": "[steps('section_appGateway').enableAppGateway]", "options": { @@ -787,7 +615,7 @@ } }, { - "name": "keyVaultText01", + "name": "sslText01", "type": "Microsoft.Common.TextBlock", "visible": "[steps('section_appGateway').enableAppGateway]", "options": { @@ -795,15 +623,7 @@ } }, { - "name": "keyVaultText02", - "type": "Microsoft.Common.TextBlock", - "visible": "[steps('section_appGateway').enableAppGateway]", - "options": { - "text": "    ⁃ Identify an Azure Key Vault: The Key Vault must already contain the certificate and its password stored as secrets." - } - }, - { - "name": "keyVaultText03", + "name": "sslText02", "type": "Microsoft.Common.TextBlock", "visible": "[steps('section_appGateway').enableAppGateway]", "options": { @@ -818,7 +638,7 @@ "name": "certificateOption", "type": "Microsoft.Common.OptionsGroup", "label": "Select desired TLS/SSL certificate option", - "defaultValue": "Upload a TLS/SSL certificate", + "defaultValue": "Generate a self-signed certificate", "toolTip": "Select desired TLS/SSL certificate option", "constraints": { "allowedValues": [ @@ -826,10 +646,6 @@ "label": "Upload a TLS/SSL certificate", "value": "haveCert" }, - { - "label": "Identify an Azure Key Vault", - "value": "haveKeyVault" - }, { "label": "Generate a self-signed certificate", "value": "generateCert" @@ -837,9 +653,10 @@ ], "required": true }, - "visible": "[steps('section_appGateway').enableAppGateway]" }, + "visible": "[steps('section_appGateway').enableAppGateway]" + }, { - "name": "keyVaultSSLCertData", + "name": "appGatewaySSLCertData", "type": "Microsoft.Common.FileUpload", "label": "TLS/SSL certificate(.pfx)", "toolTip": "TLS/SSL certificate used for App Gateway", @@ -873,82 +690,157 @@ "visible": "[equals(steps('section_appGateway').certificateOption, 'haveCert')]" }, { - "name": "keyVaultResourceGroup", - "type": "Microsoft.Common.TextBox", - "label": "Resource group name in current subscription containing the Key Vault", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1})$", - "validationMessage": "[if(greater(length(steps('section_appGateway').keyVaultResourceGroup), 90),'Resource group names only allow up to 90 characters.', 'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" - }, - "visible": "[equals(steps('section_appGateway').certificateOption, 'haveKeyVault')]" + "name": "infoGenerateCertIndentity", + "type": "Microsoft.Common.InfoBox", + "visible": "[equals(steps('section_appGateway').certificateOption, 'generateCert')]", + "options": { + "icon": "Info", + "text": "This option will create a self-signed TLS/SSL certificate for gateway TLS/SSL termination. The Azure identity deploying
    this feature must have one of the following two sets of Azure role-based access control roles:
  • Contributor and User Access Administrator of the current subscription.
  • Owner of the current subscription.
  • " + } }, { - "name": "keyVaultName", - "type": "Microsoft.Common.TextBox", - "label": "Name of the Azure Key Vault containing secrets for the certificate for TLS/SSL Termination", - "defaultValue": "", - "toolTip": "Use only letters and numbers", + "name": "sslBackendCertData", + "type": "Microsoft.Common.FileUpload", + "label": "Trusted root certificate(.cer, .cert)", + "toolTip": "Trusted root certificate (CA certificate) used to set up end to end TLS/SSL", "constraints": { "required": true, - "regex": "^(?=.{3,24}$)[a-zA-Z](([a-z0-9A-Z]*|(?:\\-[^\\-][a-z0-9A-Z]*))*)$", - "validationMessage": "[if(or(greater(length(steps('section_appGateway').keyVaultName), 24), less(length(steps('section_appGateway').keyVaultName), 3)),'Vault name must be between 3-24 alphanumeric characters. The name must begin with a letter, end with a letter or digit, and not contain consecutive hyphens.','Vault name must only contain alphanumeric characters and dashes and cannot start with a number')]" + "accept": ".cer, .cert" }, - "visible": "[equals(steps('section_appGateway').certificateOption, 'haveKeyVault')]" - }, - { - "name": "keyVaultSSLCertDataSecretName", - "type": "Microsoft.Common.TextBox", - "label": "The name of the secret in the specified Key Vault whose value is the TLS/SSL certificate data", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." + "options": { + "multiple": false, + "uploadMode": "file", + "openMode": "binary" }, - "visible": "[equals(steps('section_appGateway').certificateOption, 'haveKeyVault')]" - }, + "visible": "[and(steps('section_appGateway').enableAppGateway, steps('section_sslConfiguration').enableCustomSSL)]" + } + ], + "visible": true + }, + { + "name": "section_networkingConfiguration", + "type": "Microsoft.Common.Section", + "label": "Networking", + "elements": [ { - "name": "keyVaultSSLCertPasswordSecretName", - "type": "Microsoft.Common.TextBox", - "label": "The name of the secret in the specified Key Vault whose value is the password for the TLS/SSL certificate", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - }, - "visible": "[equals(steps('section_appGateway').certificateOption, 'haveKeyVault')]" + "name": "infoGatewaySubnet", + "type": "Microsoft.Common.InfoBox", + "visible": "[steps('section_appGateway').enableAppGateway]", + "options": { + "icon": "Warning", + "text": "Please make sure you are using a dedicated subnet for Application Gateway.", + "uri": "https://docs.microsoft.com/en-us/azure/application-gateway/configuration-infrastructure" + } }, { - "name": "infoGatewayIndentity", + "name": "vnetInfo", "type": "Microsoft.Common.InfoBox", - "visible": "[and(equals(steps('section_appGateway').certificateOption, 'generateCert'), less(length(steps('section_appGateway').gatewayIdentity.userAssignedIdentities), 1))]", + "visible": "true", "options": { - "icon": "Error", - "text": "This option will create a self-signed TLS/SSL certificate for gateway TLS/SSL termination. This option requires at least one user-assigned identity to access Azure resources.", - "uri": "https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/deployment-script-template" + "icon": "Info", + "text": "When creating a new virtual network, the subnet's address prefix is calculated automatically based on the virtual
    network's address prefix. When using an existing virtual network, a minimum virtual network size of /24 and a
    minimum subnet size of /24 are required. If deploying an Application Gateway, it must be deployed in its own
    dedicated subnet with a minimum subnet size of /29." } }, { - "name": "gatewayIdentity", - "type": "Microsoft.ManagedIdentity.IdentitySelector", - "label": "Managed Identity Configuration", + "name": "virtualNetworkWithAppGateway", + "type": "Microsoft.Network.VirtualNetworkCombo", + "visible": "[steps('section_appGateway').enableAppGateway]", + "label": { + "virtualNetwork": "Virtual network", + "subnets": "Subnets" + }, "toolTip": { - "userAssignedIdentity": "Add user-assigned identities to enable creation of TLS/SSL certificate." + "virtualNetwork": "Name of the virtual network", + "subnets": "Subnets for the virtual network" }, "defaultValue": { - "systemAssignedIdentity": "Off" + "name": "[concat('wlscluster-vnet-',take(guid(), 8))]", + "addressPrefixSize": "/23" }, - "options": { - "hideSystemAssignedIdentity": true, - "hideUserAssignedIdentity": false + "constraints": { + "minAddressPrefixSize": "/23" }, - "visible": "[equals(steps('section_appGateway').certificateOption, 'generateCert')]" + "subnets": { + "subnet1": { + "label": "Subnet for WebLogic", + "defaultValue": { + "name": "wls-subnet", + "addressPrefixSize": "/28" + }, + "constraints": { + "minAddressPrefixSize": "/29", + "minAddressCount": "[add(int(basics('basicsRequired').numberOfInstances), 1)]", + "requireContiguousAddresses": false + } + }, + "subnet2": { + "label": "Subnet for Application Gateway", + "defaultValue": { + "name": "appgateway-subnet", + "addressPrefixSize": "/24" + }, + "constraints": { + "minAddressPrefixSize": "/24", + "minAddressCount": 250, + "requireContiguousAddresses": false + } + } + } + }, + { + "name": "virtualNetworkWithoutAppGateway", + "type": "Microsoft.Network.VirtualNetworkCombo", + "visible": "[not(steps('section_appGateway').enableAppGateway)]", + "label": { + "virtualNetwork": "Virtual network", + "subnets": "Subnets" + }, + "toolTip": { + "virtualNetwork": "Name of the virtual network", + "subnets": "Subnets for the virtual network" + }, + "defaultValue": { + "name": "wls-vnet", + "addressPrefixSize": "/28" + }, + "constraints": { + "minAddressPrefixSize": "/28" + }, + "subnets": { + "subnet1": { + "label": "Subnet for WebLogic", + "defaultValue": { + "name": "wls-subnet", + "addressPrefixSize": "/28" + }, + "constraints": { + "minAddressPrefixSize": "/29", + "minAddressCount": "[add(int(basics('basicsRequired').numberOfInstances), 1)]", + "requireContiguousAddresses": false + } + } + } + }, + { + "name": "denyPublicTrafficForAdminServer", + "type": "Microsoft.Common.OptionsGroup", + "label": "Deny public traffic for admin server?", + "defaultValue": "No", + "toolTip": "Select 'Yes' to deny public traffic for admin server. Configuration here for port 7001 and 7002 has a higher priority than above.", + "visible": "[or(equals(steps('section_networkingConfiguration').virtualNetworkWithAppGateway.newOrExisting, 'new'), equals(steps('section_networkingConfiguration').virtualNetworkWithoutAppGateway.newOrExisting, 'new'))]", + "constraints": { + "allowedValues": [ + { + "label": "No", + "value": false + }, + { + "label": "Yes", + "value": true + } + ], + "required": true + } }, { "name": "denyPublicTrafficForManagedServer", @@ -969,20 +861,12 @@ ], "required": true }, - "visible": "[steps('section_appGateway').enableAppGateway]" - } - ], - "visible": true - }, - { - "name": "section_dnsConfiguration", - "type": "Microsoft.Common.Section", - "label": "DNS Configuration", - "elements": [ + "visible": "[and(steps('section_appGateway').enableAppGateway, or(equals(steps('section_networkingConfiguration').virtualNetworkWithAppGateway.newOrExisting, 'new'), equals(steps('section_networkingConfiguration').virtualNetworkWithoutAppGateway.newOrExisting, 'new')))]" + }, { "name": "dnsConfigurationText", "type": "Microsoft.Common.TextBlock", - "visible": true, + "visible": "[or(equals(steps('section_networkingConfiguration').virtualNetworkWithAppGateway.newOrExisting, 'new'), equals(steps('section_networkingConfiguration').virtualNetworkWithoutAppGateway.newOrExisting, 'new'))]", "options": { "text": "Selecting 'Yes' here will cause the template to provision Oracle WebLogic Server Administration Console and Application Gateway using a custom DNS Name (for example: applications.contoso.com)", "link": { @@ -994,7 +878,7 @@ { "name": "enableCustomDNS", "type": "Microsoft.Common.OptionsGroup", - "visible": true, + "visible": "[or(equals(steps('section_networkingConfiguration').virtualNetworkWithAppGateway.newOrExisting, 'new'), equals(steps('section_networkingConfiguration').virtualNetworkWithoutAppGateway.newOrExisting, 'new'))]", "label": "Configure Custom DNS Alias?", "defaultValue": "No", "toolTip": "Select 'Yes' to configure Custom DNS Alias.", @@ -1012,11 +896,37 @@ "required": false } }, + { + "name": "dnsLabelPrefix", + "type": "Microsoft.Common.TextBox", + "label": "DNS Label Prefix", + "toolTip": "The string to prepend to the DNS label.", + "defaultValue": "wls", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{3,10}$", + "validationMessage": "The prefix must be between 3 and 10 characters long and contain letters, numbers only." + }, + "visible": "[bool(steps('section_networkingConfiguration').enableCustomDNS)]" + }, + { + "name": "portsToExpose", + "label": "Ports and port ranges to expose (N or N-N, comma separated)", + "type": "Microsoft.Common.TextBox", + "toolTip": "Ports and port ranges to expose (N or N-N, comma separated)", + "defaultValue": "80,443,7001-9000", + "constraints": { + "required": true, + "regex": "^((([0-9]+-[0-9]+)|([0-9]+))[,]?)+[^,]$", + "validationMessage": "Only numbers, hyphen separated ranges of numbers, separated by commas" + }, + "visible": "[bool(steps('section_networkingConfiguration').enableCustomDNS)]" + }, { "name": "customDNSSettings", "type": "Microsoft.Common.Section", "label": "DNS Configuration Settings", - "visible": "[bool(steps('section_dnsConfiguration').enableCustomDNS)]", + "visible": "[bool(steps('section_networkingConfiguration').enableCustomDNS)]", "elements": [ { "name": "bringDNSZone", @@ -1040,7 +950,7 @@ { "name": "createDNSZoneText", "type": "Microsoft.Common.InfoBox", - "visible": "[not(bool(steps('section_dnsConfiguration').customDNSSettings.bringDNSZone))]", + "visible": "[not(bool(steps('section_networkingConfiguration').customDNSSettings.bringDNSZone))]", "options": { "icon": "Info", "text": "You must perform DNS Domain Delegation at your DNS Registry after deployment.", @@ -1048,12 +958,23 @@ } }, { - "name": "deplymentScriptInfo", - "type": "Microsoft.Common.TextBlock", + "name": "createDNSZonePublicResolveWarning", + "type": "Microsoft.Common.InfoBox", + "visible": "[bool(steps('section_networkingConfiguration').customDNSSettings.bringDNSZone)]", "options": { - "text": "If you choose to use an existing Azure DNS Zone, you must select a user-assigned managed identity to enable the necessary configuration." - }, - "visible": "[steps('section_dnsConfiguration').customDNSSettings.bringDNSZone]" + "icon": "Info", + "text": "The referenced hostnames must be publicly resolvable before deployment.", + "uri": "https://learn.microsoft.com/en-us/azure/dns/dns-getstarted-portal" + } + }, + { + "name": "infoDNSIndentity", + "type": "Microsoft.Common.InfoBox", + "visible": "[bool(steps('section_networkingConfiguration').customDNSSettings.bringDNSZone)]", + "options": { + "icon": "Info", + "text": "This option will add/update records in your Azure DNS Zone. The Azure identity deploying this feature must have one of the following two sets of Azure role-based access control roles:
  • Contributor and User Access Administrator of the current subscription.
  • Owner of the current subscription.
  • " + } }, { "name": "dnszoneName", @@ -1076,9 +997,9 @@ "constraints": { "required": true, "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1})$", - "validationMessage": "[if(greater(length(steps('section_dnsConfiguration').existingDNSZonesSettings.dnsZoneResourceGroup), 90),'Resource group names only allow up to 90 characters.', 'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" + "validationMessage": "[if(greater(length(steps('section_networkingConfiguration').existingDNSZonesSettings.dnsZoneResourceGroup), 90),'Resource group names only allow up to 90 characters.', 'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" }, - "visible": "[steps('section_dnsConfiguration').customDNSSettings.bringDNSZone]" + "visible": "[steps('section_networkingConfiguration').customDNSSettings.bringDNSZone]" }, { "name": "dnszoneAdminConsoleLabel", @@ -1094,7 +1015,7 @@ "message": "Each label must contain between 1 and 63 characters. Each label must only contain letters, numbers, underscores, and dashes." }, { - "isValid": "[less(sub(length(concat(steps('section_dnsConfiguration').customDNSSettings.dnszoneAdminConsoleLabel,'.',steps('section_dnsConfiguration').customDNSSettings.dnszoneName)),length(replace(concat(steps('section_dnsConfiguration').customDNSSettings.dnszoneAdminConsoleLabel,'.',steps('section_dnsConfiguration').customDNSSettings.dnszoneName), '.', ''))),34)]", + "isValid": "[less(sub(length(concat(steps('section_networkingConfiguration').customDNSSettings.dnszoneAdminConsoleLabel,'.',steps('section_networkingConfiguration').customDNSSettings.dnszoneName)),length(replace(concat(steps('section_networkingConfiguration').customDNSSettings.dnszoneAdminConsoleLabel,'.',steps('section_networkingConfiguration').customDNSSettings.dnszoneName), '.', ''))),34)]", "message": "Subdomain must be between 2 and 34 labels. For example, \"admin.contoso.com\" has 3 labels." } ] @@ -1114,58 +1035,12 @@ "message": "Each label must contain between 1 and 63 characters. Each label must only contain letters, numbers, underscores, and dashes." }, { - "isValid": "[less(sub(length(concat(if(empty(steps('section_dnsConfiguration').customDNSSettings.dnszoneGatewayLabel), '', steps('section_dnsConfiguration').customDNSSettings.dnszoneGatewayLabel),'.',steps('section_dnsConfiguration').customDNSSettings.dnszoneName)),length(replace(concat(if(empty(steps('section_dnsConfiguration').customDNSSettings.dnszoneGatewayLabel), '', steps('section_dnsConfiguration').customDNSSettings.dnszoneGatewayLabel),'.',steps('section_dnsConfiguration').customDNSSettings.dnszoneName), '.', ''))),34)]", + "isValid": "[less(sub(length(concat(if(empty(steps('section_networkingConfiguration').customDNSSettings.dnszoneGatewayLabel), '', steps('section_networkingConfiguration').customDNSSettings.dnszoneGatewayLabel),'.',steps('section_networkingConfiguration').customDNSSettings.dnszoneName)),length(replace(concat(if(empty(steps('section_networkingConfiguration').customDNSSettings.dnszoneGatewayLabel), '', steps('section_networkingConfiguration').customDNSSettings.dnszoneGatewayLabel),'.',steps('section_networkingConfiguration').customDNSSettings.dnszoneName), '.', ''))),34)]", "message": "Subdomain must be between 2 and 34 labels. For example, \"applications.contoso.com\" has 3 labels." } ] }, - "visible": "[and(bool(steps('section_appGateway').enableAppGateway), bool(steps('section_dnsConfiguration').enableCustomDNS))]" - }, - { - "name": "reuseIdentity", - "type": "Microsoft.Common.OptionsGroup", - "label": "Use the Managed Identity seleted previousely?", - "defaultValue": "Yes", - "toolTip": "Select 'Yes' to reuse the Managed Identity seleted previousely, 'No' to input a new identity.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": true - }, - { - "label": "No", - "value": false - } - ] - }, - "visible": "[and(greater(length(steps('section_appGateway').gatewayIdentity.userAssignedIdentities),0), bool(steps('section_dnsConfiguration').customDNSSettings.bringDNSZone))]" - }, - { - "name": "infoDNSIndentity", - "type": "Microsoft.Common.InfoBox", - "visible": "[and(bool(steps('section_dnsConfiguration').customDNSSettings.bringDNSZone), less(length(steps('section_appGateway').gatewayIdentity.userAssignedIdentities),1), less(length(steps('section_dnsConfiguration').customDNSSettings.dnsIdentity.userAssignedIdentities), 1))]", - "options": { - "icon": "Error", - "text": "This option will use Azure deployment scripts to update records to your Azure DNS Zone. You have to add at least one user-assigned identity to access Azure resources.", - "uri": "https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/deployment-script-template" - } - }, - { - "name": "dnsIdentity", - "type": "Microsoft.ManagedIdentity.IdentitySelector", - "label": "Managed Identity Configuration", - "toolTip": { - "userAssignedIdentity": "Add user-assigned identities to grant the resource access to Azure resources." - }, - "defaultValue": { - "systemAssignedIdentity": "Off" - }, - "options": { - "hideSystemAssignedIdentity": true, - "hideUserAssignedIdentity": false - }, - "visible": "[if(greater(length(steps('section_appGateway').gatewayIdentity.userAssignedIdentities),0),and(equals(steps('section_dnsConfiguration').customDNSSettings.reuseIdentity, false), bool(steps('section_dnsConfiguration').customDNSSettings.bringDNSZone)), bool(steps('section_dnsConfiguration').customDNSSettings.bringDNSZone))]" + "visible": "[and(bool(steps('section_appGateway').enableAppGateway), bool(steps('section_networkingConfiguration').enableCustomDNS))]" } ] } @@ -1223,7 +1098,7 @@ "constraints": { "allowedValues": [ { - "label": "Azure database for PostgreSQL", + "label": "PostgreSQL (Supports passwordless connection)", "value": "postgresql" }, { @@ -1231,14 +1106,27 @@ "value": "oracle" }, { - "label": "Azure SQL", + "label": "Microsoft SQL Server (Supports passwordless connection)", "value": "sqlserver" + }, + { + "label": "MySQL (Supports passwordless connection)", + "value": "mysql" } ], "required": true }, "visible": true }, + { + "name": "mysqlJDBCDriverInfo", + "type": "Microsoft.Common.InfoBox", + "visible": "[and(bool(steps('section_database').enableDB),equals(steps('section_database').databaseConnectionInfo.databaseType, 'mysql'))]", + "options": { + "icon": "Info", + "text": "To support passwordless connection and various functionalities, the offer will upgrade the
    Oracle WebLogic Server MySQL driver with recent MySQL Connector Java driver." + } + }, { "name": "jdbcDataSourceName", "type": "Microsoft.Common.TextBox", @@ -1246,9 +1134,13 @@ "toolTip": "The JNDI name for the database JDBC connection", "defaultValue": "", "constraints": { - "required": "[bool(steps('section_database').enableDB)]", - "regex": "^[a-z0-9A-Z/]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters, numbers, and slashes (/)." + "required": true, + "validations": [ + { + "regex": "^[a-z0-9A-Z/]{1,30}$", + "message": "The value must be 1-30 characters long and must only contain letters, numbers, and slashes (/)." + } + ] }, "visible": true }, @@ -1259,12 +1151,82 @@ "toolTip": "The JDBC connection string for the database", "defaultValue": "", "constraints": { - "required": "[bool(steps('section_database').enableDB)]", - "regex": "[concat('^jdbc:', coalesce(steps('section_database').databaseConnectionInfo.databaseType, ''), '.*$')]", - "validationMessage": "A valid JDBC URL for the chosen database type must be provided" + "required": true, + "validations": [ + { + "regex": "^jdbc:.*$", + "message": "A valid JDBC URL must start with 'jdbc:'." + }, + { + "isValid": "[startsWith(steps('section_database').databaseConnectionInfo.dsConnectionURL, concat('jdbc:', steps('section_database').databaseConnectionInfo.databaseType))]", + "message": "A valid JDBC URL for the chosen database type must be provided." + }, + { + "isValid": "[if(and(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection), equals(steps('section_database').databaseConnectionInfo.databaseType, 'mysql')), and(not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'defaultAuthenticationPlugin')),not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'authenticationPlugins')), not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'azure.clientId'))), 'true')]", + "message": "The offer will append defaultAuthenticationPlugin, authenticationPlugins with Azure provided plugins, and append azure.clientId with your managed identity client ID automatically, please do not specify them in your connection string." + }, + { + "isValid": "[if(and(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection), equals(steps('section_database').databaseConnectionInfo.databaseType, 'postgresql')), and(not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'authenticationPluginClassName')),not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'azure.clientId'))), 'true')]", + "message": "The offer will append authenticationPluginClassName with Azure provided plugins, and append azure.clientId with your managed identity client ID automatically, please do not specify them in your connection string." + }, + { + "isValid": "[if(and(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection), equals(steps('section_database').databaseConnectionInfo.databaseType, 'sqlserver')), and(not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'authentication=ActiveDirectoryMSI')),not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'msiClientId'))), 'true')]", + "message": "The offer will append authentication with ActiveDirectoryMSI, and append msiClientId with your managed identity client ID automatically, please do not specify them in your connection string." + }, + { + "isValid": "[if(and(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection0),equals(steps('section_database').databaseConnectionInfo.databaseType, 'sqlserver')), greater(length(steps('section_database').databaseConnectionInfo.dbIdentity.userAssignedIdentities),0), bool('true'))]", + "message": "You must select at least one managed identity that has access to your database." + } + ] + }, + "visible": true + }, + { + "name": "dbGlobalTranPro", + "type": "Microsoft.Common.DropDown", + "label": "Global transactions protocol", + "defaultValue": "OnePhaseCommit", + "multiLine": true, + "toolTip": "Determines the transaction protocol (global transaction processing behavior) for the data source.", + "constraints": { + "allowedValues": [ + { + "label": "TwoPhaseCommit", + "description": "Standard XA transaction processing. Requires an XA driver.", + "value": "TwoPhaseCommit" + }, + { + "label": "LoggingLastResource", + "description": "A performance enhancement for one non-XA resource.", + "value": "LoggingLastResource" + }, + { + "label": "EmulateTwoPhaseCommit", + "description": "Enables one non-XA resource to participate in a global transaction, but has some risk to data.", + "value": "EmulateTwoPhaseCommit" + }, + { + "label": "OnePhaseCommit", + "description": "One-phase XA transaction processing using a non-XA driver. This is the default setting.", + "value": "OnePhaseCommit" + }, + { + "label": "None", + "description": "Support for local transactions only.", + "value": "None" + } + ], + "required": true }, "visible": true }, + { + "name": "enablePswlessConnection0", + "type": "Microsoft.Common.CheckBox", + "label": "Use passwordless datasource connection", + "toolTip": "Use passwordless datasource connection.", + "visible": "[and(bool(steps('section_database').enableDB),equals(steps('section_database').databaseConnectionInfo.databaseType, 'sqlserver'))]" + }, { "name": "dbUser", "type": "Microsoft.Common.TextBox", @@ -1272,11 +1234,26 @@ "toolTip": "Use only letters and numbers", "defaultValue": "", "constraints": { - "required": "[bool(steps('section_database').enableDB)]", - "regex": "^(?!\\-)([a-z0-9A-Z@\\-]{1,128})([^\\-])$", - "validationMessage": "The value must be 1-128 characters long and must only contain letters, numbers, hyphen(-) and the at sign, no hyphen allowed at the beginning and the end of database username." + "required": true, + "validations": [ + { + "regex": "^(?!\\-)([a-z0-9A-Z@\\-]{1,128})([^\\-])$", + "message": "The value must be 1-128 characters long and must only contain letters, numbers, hyphen(-) and the at sign, no hyphen allowed at the beginning and the end of database username." + }, + { + "isValid": "[if(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection), greater(length(steps('section_database').databaseConnectionInfo.dbIdentity.userAssignedIdentities),0), bool('true'))]", + "message": "You must select at least one managed identity that has access to your database." + } + ] }, - "visible": true + "visible": "[and(bool(steps('section_database').enableDB), not(and(steps('section_database').databaseConnectionInfo.enablePswlessConnection0, equals(steps('section_database').databaseConnectionInfo.databaseType, 'sqlserver'))))]" + }, + { + "name": "enablePswlessConnection", + "type": "Microsoft.Common.CheckBox", + "label": "Use passwordless datasource connection", + "toolTip": "Use passwordless datasource connection.", + "visible": "[and(bool(steps('section_database').enableDB),or(equals(steps('section_database').databaseConnectionInfo.databaseType, 'mysql'),equals(steps('section_database').databaseConnectionInfo.databaseType, 'postgresql')))]" }, { "name": "dbPassword", @@ -1287,342 +1264,33 @@ }, "toolTip": "Database Password", "constraints": { - "required": "[bool(steps('section_database').enableDB)]", + "required": true, "regex": "^((?=.*[0-9])(?=.*[a-zA-Z!@#$%^&*])).{5,128}$", - "validationMessage": "The password must be between five and 128 characters long and have at least one number." + "validationMessage": "The password must be between 5 and 128 characters long and have at least one number." }, "options": { "hideConfirmation": false }, - "visible": true - } - ], - "visible": "[bool(steps('section_database').enableDB)]" - } - ] - }, - { - "name": "section_aad", - "label": "Azure Active Directory", - "subLabel": { - "preValidation": "Configure the connection to Azure Active Directory.", - "postValidation": "Done" - }, - "bladeTitle": "Azure Active Directory", - "elements": [ - { - "name": "aboutAad", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "icon": "None", - "text": "Selecting 'Yes' here and providing the configuration will cause the template to configure the connection to Azure Active Directory.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-cluster-aad-ldap" - } - } - }, - { - "name": "enableAAD", - "type": "Microsoft.Common.OptionsGroup", - "label": "Connect to Azure Active Directory?", - "defaultValue": "No", - "toolTip": "Select 'Yes' and provide required info to configure the connection to Azure Active Directory.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": "true" - }, - { - "label": "No", - "value": "false" - } - ], - "required": true - } - }, - { - "name": "aadInfo", - "type": "Microsoft.Common.Section", - "label": "Connection settings", - "elements": [ - { - "name": "aadsServerHost", - "type": "Microsoft.Common.TextBox", - "label": "Server Host", - "toolTip": "The LDAP server host.", - "defaultValue": "", - "constraints": { - "required": true, - "regex": "(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]", - "validationMessage": "The value must be a valid host name." - } - }, - { - "name": "aadsPublicIP", - "type": "Microsoft.Common.TextBox", - "label": "Secure LDAP external IP address", - "toolTip": "Secure LDAP external IP address.", - "constraints": { - "required": true, - "regex": "\\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.|$)){4}\\b", - "validationMessage": "The value must be a valid IP address." - } - }, - { - "name": "aadsPortNumber", - "type": "Microsoft.Common.TextBox", - "label": "Port", - "toolTip": "The port number of LDAP Server, default is 636.", - "defaultValue": "636", - "constraints": { - "required": true, - "regex": "^[0-9]+$", - "validationMessage": "The value must be numbers." - } - }, - { - "name": "wlsLDAPProviderName", - "type": "Microsoft.Common.TextBox", - "label": "Provider Name", - "defaultValue": "AzureActiveDirectoryProvider", - "toolTip": "The value used for creating authentication provider name of WebLogic Server.", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{3,50}$", - "validationMessage": "The Provider Name must be between 3 and 50 characters long and contain letters, numbers only." - } - }, - { - "name": "wlsLDAPPrincipal", - "type": "Microsoft.Common.TextBox", - "label": "Principal", - "toolTip": "The Distinguished Name (DN) of the LDAP user that WebLogic Server should use to connect to the LDAP server.", - "constraints": { - "required": true, - "regex": ".+,dc|DC=([^,]+),dc|DC=([^,]+)$", - "validationMessage": "The value must be valid LDAP user distinguished name." - } - }, - { - "name": "wlsLDAPPrincipalPassword", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Password for Principal", - "confirmPassword": "Confirm password" - }, - "toolTip": "The credential (usually a password) used to connect to the LDAP server.", - "constraints": { - "required": true - } - }, - { - "name": "wlsLDAPUserBaseDN", - "type": "Microsoft.Common.TextBox", - "label": "User Base DN", - "toolTip": "The base distinguished name (DN) of the tree in the LDAP directory that contains users.", - "constraints": { - "required": true, - "regex": ".+,dc|DC=([^,]+),dc|DC=([^,]+)$", - "validationMessage": "The value must be valid LDAP user based distinguished name." - } - }, - { - "name": "wlsLDAPGroupBaseDN", - "type": "Microsoft.Common.TextBox", - "label": "Group Base DN", - "toolTip": "The base distinguished name (DN) of the tree in the LDAP directory that contains groups.", - "constraints": { - "required": true, - "regex": ".+,dc|DC=([^,]+),dc|DC=([^,]+)$", - "validationMessage": "The value must be valid LDAP group based distinguished name." - } + "visible": "[and(bool(steps('section_database').enableDB), not(or(steps('section_database').databaseConnectionInfo.enablePswlessConnection, steps('section_database').databaseConnectionInfo.enablePswlessConnection0)))]" }, { - "name": "wlsLDAPSSLCertificate", - "type": "Microsoft.Common.FileUpload", - "label": "Client certificate for TLS/SSL Configuration (.cer)", - "toolTip": "Client certificate of AAD LADP server, used to configure the Trust Keystore to enable TLS/SSL in Oracle WebLogic Server.", - "constraints": { - "required": true, - "accept": ".cer" + "name": "dbIdentity", + "type": "Microsoft.ManagedIdentity.IdentitySelector", + "label": "Connect database with Managed Identity", + "toolTip": { + "userAssignedIdentity": "Select a user assigned identity that has access to your database. For how to create a database user for your managed identity, see https://aka.ms/javaee-db-identity." }, - "options": { - "multiple": false, - "uploadMode": "file", - "openMode": "binary" - } - } - ], - "visible": "[bool(steps('section_aad').enableAAD)]" - } - ] - }, - { - "name": "section_elk", - "label": "Elasticsearch and Kibana", - "subLabel": { - "preValidation": "Configure the connection to Elasticsearch and Kibana to store WLS logs.", - "postValidation": "Done" - }, - "bladeTitle": "Elasticsearch and Kibana", - "elements": [ - { - "name": "aboutelk", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "icon": "None", - "text": "Selecting 'Yes' here and providing the configuration will cause the template to configure Elasticsearch and Kibana to store WLS logs.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-elk-tutorial" - } - } - }, - { - "name": "enableELK", - "type": "Microsoft.Common.OptionsGroup", - "label": "Export logs to Elasticsearch?", - "defaultValue": "No", - "toolTip": "Select 'Yes' and provide required info to configure the connection to Elasticsearch.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": "true" + "defaultValue": { + "systemAssignedIdentity": "Off" }, - { - "label": "No", - "value": "false" - } - ], - "required": true - } - }, - { - "name": "elkInfo", - "type": "Microsoft.Common.Section", - "label": "Connection settings", - "elements": [ - { - "name": "elkMemoryRequiredText", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "icon": "None", - "text": "To ensure Logstash works correctly, the selected Virtual Machines have at least 2.5GB memory.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-elk" - } - } - }, - { - "name": "elkMemoryRequired", - "type": "Microsoft.Common.InfoBox", "options": { - "icon": "Error", - "text": "Your selected Virtual Machines have less than 2.5GB memory to set up Elasticsearch and Kibana, please go to Basics -> Virtual machine size to change it, recommended size is Standard_A2_v2." - }, - "visible": "[and(contains('Standard_A1,Basic_A1,Standard_B1ms,Standard_A1_v2,Standard_F1,Standard_F1s', basics('vmSizeSelect')),bool(steps('section_elk').enableELK))]" - }, - { - "name": "elasticsearchEndpoint", - "type": "Microsoft.Common.TextBox", - "label": "Elasticsearch endpoint URL", - "toolTip": "Elasticsearch endpoint.", - "defaultValue": "https://example.location.azure.elastic-cloud.com:9243", - "constraints": { - "required": true, - "validations": [ - { - "regex": "^https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*):[0-9]{1,6}$", - "message": "The value must be a valid endpoint." - }, - { - "isValid": "[not(contains('Standard_A1,Basic_A1,Standard_B1ms,Standard_A1_v2,Standard_F1,Standard_F1s', basics('vmSizeSelect')))]", - "message": "Your selected Virtual Machines have less than 2.5GB memory to set up Elasticsearch and Kibana, please go to Basics -> Virtual machine size to change it, recommended size is Standard_A2_v2." - } - ] - } - }, - { - "name": "elasticsearchUserName", - "type": "Microsoft.Common.TextBox", - "label": "Elasticsearch User Name", - "defaultValue": "elastic", - "toolTip": "User name of Elasticsearch account.", - "constraints": { - "required": true, - "regex": "^(?!\\-)([a-z0-9A-Z@\\-]{1,128})([^\\-])", - "validationMessage": "The value must be valid Elasticsearch user name." - } - }, - { - "name": "elasticsearchPassword", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Password for Elasticsearch account", - "confirmPassword": "Confirm password" + "hideSystemAssignedIdentity": true, + "hideUserAssignedIdentity": false }, - "toolTip": "Password for Elasticsearch account.", - "constraints": { - "required": true - } - }, - { - "name": "logsToIntegrate", - "type": "Microsoft.Common.DropDown", - "label": "WebLogic Server logs to export", - "toolTip": "The logs selected will be exported to Elasticsearch.", - "defaultValue": [ - "Server Log" - ], - "multiselect": true, - "selectAll": true, - "multiLine": true, - "defaultDescription": "The logs selected will be exported to Elasticsearch", - "constraints": { - "allowedValues": [ - { - "label": "Data Source Log", - "description": "Export Datasource logs to Elasticsearch.", - "value": "DataSourceLog" - }, - { - "label": "Domain Log", - "description": "Export Domain logs to Elasticsearch.", - "value": "DomainLog" - }, - { - "label": "HTTP Access Log", - "description": "Export HTTP logs to Elasticsearch.", - "value": "HTTPAccessLog" - }, - { - "label": "Node Manager Logs", - "description": "Export Node Manager logs to Elasticsearch.", - "value": "NodeManagerLog" - }, - { - "label": "Server Log", - "description": "Export Server logs to Elasticsearch.", - "value": "ServerLog" - }, - { - "label": "Standard error and output", - "description": "Export standard error and output to Elasticsearch.", - "value": "StandardErrorAndOutput" - } - ], - "required": true - } + "visible": "[and(bool(steps('section_database').enableDB), or(steps('section_database').databaseConnectionInfo.enablePswlessConnection, steps('section_database').databaseConnectionInfo.enablePswlessConnection0))]" } ], - "visible": "[bool(steps('section_elk').enableELK)]" + "visible": "[bool(steps('section_database').enableDB)]" } ] }, @@ -1640,7 +1308,6 @@ "type": "Microsoft.Common.TextBlock", "visible": true, "options": { - "icon": "None", "text": "Selecting 'Yes' here and providing the configuration will cause the template to configure the Coherence cluster, the WebLogic Domain will be configured with a data tier for cache.", "link": { "label": "Learn more", @@ -1729,79 +1396,85 @@ "visible": "[bool(steps('section_coherence').enableCoherence)]" } ] + }, + { + "name": "section_tags", + "label": "Tags", + "elements": [ + { + "name": "tagsByResource", + "type": "Microsoft.Common.TagsByResource", + "resources": [ + "${identifier.applicationGateways}", + "${identifier.virtualMachines}", + "${identifier.virtualMachinesExtensions}", + "${identifier.publicIPAddresses}", + "${identifier.availabilitySets}", + "${identifier.vaults}", + "${identifier.userAssignedIdentities}", + "${identifier.dnszones}", + "${identifier.networkInterfaces}", + "${identifier.networkSecurityGroups}", + "${identifier.privateEndpoints}", + "${identifier.virtualNetworks}", + "${identifier.deploymentScripts}", + "${identifier.storageAccounts}", + "${identifier.resourcesDeployment}" + ], + "toolTip": "Tags help you organize your resources and categorize them for billing or management purposes. You can apply tags to resources deployed by the offer." + } + ] } ], "outputs": { "Location": "[location()]", - "aadsPortNumber": "[steps('section_aad').aadInfo.aadsPortNumber]", - "aadsPublicIP": "[steps('section_aad').aadInfo.aadsPublicIP]", - "aadsServerHost": "[steps('section_aad').aadInfo.aadsServerHost]", "adminPasswordOrKey": "[if(equals(basics('basicsRequired').adminPasswordOrKey.authenticationType, 'password'), basics('basicsRequired').adminPasswordOrKey.password, basics('basicsRequired').adminPasswordOrKey.sshPublicKey)]", "adminUsername": "[basics('basicsRequired').adminUsername]", + "addressPrefixes": "[if(steps('section_appGateway').enableAppGateway, steps('section_networkingConfiguration').virtualNetworkWithAppGateway.addressPrefixes, steps('section_networkingConfiguration').virtualNetworkWithoutAppGateway.addressPrefixes)]", "appGatewayCertificateOption": "[steps('section_appGateway').certificateOption]", - "appGatewayIdentity": "[steps('section_appGateway').gatewayIdentity]", - "appGatewaySSLCertData": "[steps('section_appGateway').keyVaultSSLCertData]", + "appGatewaySSLBackendCertData": "[steps('section_appGateway').sslBackendCertData]", + "appGatewaySSLCertData": "[steps('section_appGateway').appGatewaySSLCertData]", "appGatewaySSLCertPassword": "[steps('section_appGateway').appGatewaySSLCertPassword]", "authenticationType": "[basics('basicsRequired').adminPasswordOrKey.authenticationType]", "enableDB": "[bool(steps('section_database').enableDB)]", "databaseType": "[steps('section_database').databaseConnectionInfo.databaseType]", - "denyPublicTrafficForAdminServer": "[basics('basicsOptional').denyPublicTrafficForAdminServer]", - "denyPublicTrafficForManagedServer": "[steps('section_appGateway').denyPublicTrafficForManagedServer]", - "dnsLabelPrefix": "[basics('basicsOptional').dnsLabelPrefix]", - "dnszoneIdentity": "[if(greater(length(steps('section_dnsConfiguration').customDNSSettings.dnsIdentity.userAssignedIdentities),0),steps('section_dnsConfiguration').customDNSSettings.dnsIdentity, steps('section_appGateway').gatewayIdentity)]", - "dnszoneName": "[steps('section_dnsConfiguration').customDNSSettings.dnszoneName]", - "dnszoneResourceGroup": "[steps('section_dnsConfiguration').customDNSSettings.dnsZoneResourceGroup]", - "dnszoneAdminConsoleLabel": "[steps('section_dnsConfiguration').customDNSSettings.dnszoneAdminConsoleLabel]", - "dnszoneAppGatewayLabel": "[steps('section_dnsConfiguration').customDNSSettings.dnszoneGatewayLabel]", + "denyPublicTrafficForAdminServer": "[steps('section_networkingConfiguration').denyPublicTrafficForAdminServer]", + "denyPublicTrafficForManagedServer": "[steps('section_networkingConfiguration').denyPublicTrafficForManagedServer]", + "dnsLabelPrefix": "[steps('section_networkingConfiguration').dnsLabelPrefix]", + "dnszoneName": "[steps('section_networkingConfiguration').customDNSSettings.dnszoneName]", + "dnszoneResourceGroup": "[steps('section_networkingConfiguration').customDNSSettings.dnsZoneResourceGroup]", + "dnszoneAdminConsoleLabel": "[steps('section_networkingConfiguration').customDNSSettings.dnszoneAdminConsoleLabel]", + "dnszoneAppGatewayLabel": "[steps('section_networkingConfiguration').customDNSSettings.dnszoneGatewayLabel]", "dsConnectionURL": "[steps('section_database').databaseConnectionInfo.dsConnectionURL]", + "dbGlobalTranPro": "[steps('section_database').databaseConnectionInfo.dbGlobalTranPro]", + "dbIdentity": "[steps('section_database').databaseConnectionInfo.dbIdentity]", "dbPassword": "[steps('section_database').databaseConnectionInfo.dbPassword]", "dbUser": "[steps('section_database').databaseConnectionInfo.dbUser]", - "elasticsearchEndpoint": "[steps('section_elk').elkInfo.elasticsearchEndpoint]", - "elasticsearchPassword": "[steps('section_elk').elkInfo.elasticsearchPassword]", - "elasticsearchUserName": "[steps('section_elk').elkInfo.elasticsearchUserName]", - "enableAAD": "[bool(steps('section_aad').enableAAD)]", "enableAppGateway": "[steps('section_appGateway').enableAppGateway]", "enableCoherence": "[bool(steps('section_coherence').enableCoherence)]", "enableCoherenceWebLocalStorage": "[bool(if(bool(steps('section_coherence').enableCoherence),steps('section_coherence').coherenceInfo.enableCoherenceWebLocalStorage,'false'))]", - "enableDNSConfiguration": "[bool(steps('section_dnsConfiguration').enableCustomDNS)]", - "enableELK": "[bool(steps('section_elk').enableELK)]", - "hasDNSZones": "[bool(if(bool(steps('section_dnsConfiguration').enableCustomDNS), steps('section_dnsConfiguration').customDNSSettings.bringDNSZone, 'false'))]", + "enableCookieBasedAffinity": "[bool(steps('section_appGateway').enableCookieBasedAffinity)]", + "enableDNSConfiguration": "[bool(steps('section_networkingConfiguration').enableCustomDNS)]", + "enablePswlessConnection": "[or(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection), bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection0))]", + "hasDNSZones": "[bool(if(bool(steps('section_networkingConfiguration').enableCustomDNS), steps('section_networkingConfiguration').customDNSSettings.bringDNSZone, 'false'))]", "jdbcDataSourceName": "[steps('section_database').databaseConnectionInfo.jdbcDataSourceName]", - "logsToIntegrate": "[steps('section_elk').elkInfo.logsToIntegrate]", - "keyVaultName": "[steps('section_appGateway').keyVaultName]", - "keyVaultResourceGroup": "[steps('section_appGateway').keyVaultResourceGroup]", - "keyVaultSSLCertDataSecretName": "[steps('section_appGateway').keyVaultSSLCertDataSecretName]", - "keyVaultSSLCertPasswordSecretName": "[steps('section_appGateway').keyVaultSSLCertPasswordSecretName]", "managedServerPrefix": "[basics('basicsOptional').managedServerPrefix]", "numberOfCoherenceCacheInstances": "[int(if(bool(steps('section_coherence').enableCoherence),steps('section_coherence').coherenceInfo.numberOfCoherenceCacheInstances,'1'))]", "numberOfInstances": "[int(basics('basicsRequired').numberOfInstances)]", - "portsToExpose": "[basics('basicsOptional').portsToExpose]", + "portsToExpose": "[steps('section_networkingConfiguration').portsToExpose]", "skuUrnVersion": "[basics('skuUrnVersion')]", "useSystemAssignedManagedIdentity": "[basics('basicsOptional').useSystemAssignedManagedIdentity]", - "vmSizeSelect": "[basics('vmSizeSelect')]", + "vmSize": "[basics('vmSizeSelect')]", "vmSizeSelectForCoherence": "[steps('section_coherence').coherenceInfo.coherenceVMSizeSelect]", "wlsDomainName": "[basics('basicsOptional').wlsDomainName]", - "wlsLDAPGroupBaseDN": "[steps('section_aad').aadInfo.wlsLDAPGroupBaseDN]", - "wlsLDAPPrincipal": "[steps('section_aad').aadInfo.wlsLDAPPrincipal]", - "wlsLDAPPrincipalPassword": "[steps('section_aad').aadInfo.wlsLDAPPrincipalPassword]", - "wlsLDAPProviderName": "[steps('section_aad').aadInfo.wlsLDAPProviderName]", - "wlsLDAPSSLCertificate": "[steps('section_aad').aadInfo.wlsLDAPSSLCertificate]", - "wlsLDAPUserBaseDN": "[steps('section_aad').aadInfo.wlsLDAPUserBaseDN]", "wlsPassword": "[basics('basicsRequired').wlsPassword]", "wlsUserName": "[basics('basicsRequired').wlsUserName]", "enableHTTPAdminListenPort": "[basics('basicsOptional').enableAdminHTTPListenPort]", - "enableCustomSSL":"[steps('section_sslConfiguration').enableCustomSSL]", - "sslConfigurationAccessOption": "[steps('section_sslConfiguration').sslConfigurationAccessOption]", - "adminSSLKeyVaultResourceGroup": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.adminSSLKeyVaultResourceGroup]", - "adminSSLKeyVaultName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.adminSSLKeyVaultName]", - "keyVaultCustomIdentityKeyStoreDataSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomIdentityKeyStoreDataSecretName]", - "keyVaultCustomIdentityKeyStorePassPhraseSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomIdentityKeyStorePassPhraseSecretName]", - "keyVaultCustomIdentityKeyStoreType": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomIdentityKeyStoreType]", - "keyVaultCustomTrustKeyStoreDataSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomTrustKeyStoreDataSecretName]", - "keyVaultCustomTrustKeyStorePassPhraseSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomTrustKeyStorePassPhraseSecretName]", - "keyVaultCustomTrustKeyStoreType": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomTrustKeyStoreType]", - "keyVaultPrivateKeyAliasSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultPrivateKeyAliasSecretName]", - "keyVaultPrivateKeyPassPhraseSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultPrivateKeyPassPhraseSecretName]", + "enableCustomSSL": "[steps('section_sslConfiguration').enableCustomSSL]", + "subnetName": "[if(steps('section_appGateway').enableAppGateway, steps('section_networkingConfiguration').virtualNetworkWithAppGateway.subnets.subnet1.name, steps('section_networkingConfiguration').virtualNetworkWithoutAppGateway.subnets.subnet1.name)]", + "subnetPrefix": "[if(steps('section_appGateway').enableAppGateway, steps('section_networkingConfiguration').virtualNetworkWithAppGateway.subnets.subnet1.addressPrefix, steps('section_networkingConfiguration').virtualNetworkWithoutAppGateway.subnets.subnet1.addressPrefix)]", + "subnetForAppGateway": "[steps('section_networkingConfiguration').virtualNetworkWithAppGateway.subnets.subnet2.name]", + "subnetPrefixForAppGateway": "[steps('section_networkingConfiguration').virtualNetworkWithAppGateway.subnets.subnet2.addressPrefix]", "uploadedCustomIdentityKeyStoreData": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomIdentityKeyStoreData]", "uploadedCustomIdentityKeyStorePassphrase": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomIdentityKeyStorePassphrase]", "uploadedCustomIdentityKeyStoreType": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomIdentityKeyStoreType]", @@ -1809,7 +1482,11 @@ "uploadedCustomTrustKeyStorePassPhrase": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomTrustKeyStorePassPhrase]", "uploadedCustomTrustKeyStoreType": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomTrustKeyStoreType]", "uploadedPrivateKeyAlias": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedPrivateKeyAlias]", - "uploadedPrivateKeyPassPhrase": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedPrivateKeyPassPhrase]" + "uploadedPrivateKeyPassPhrase": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedPrivateKeyPassPhrase]", + "virtualNetworkName": "[if(steps('section_appGateway').enableAppGateway, steps('section_networkingConfiguration').virtualNetworkWithAppGateway.name, steps('section_networkingConfiguration').virtualNetworkWithoutAppGateway.name)]", + "virtualNetworkResourceGroupName": "[if(steps('section_appGateway').enableAppGateway, steps('section_networkingConfiguration').virtualNetworkWithAppGateway.resourceGroup, steps('section_networkingConfiguration').virtualNetworkWithoutAppGateway.resourceGroup)]", + "virtualNetworkNewOrExisting": "[if(steps('section_appGateway').enableAppGateway, steps('section_networkingConfiguration').virtualNetworkWithAppGateway.newOrExisting, steps('section_networkingConfiguration').virtualNetworkWithoutAppGateway.newOrExisting)]", + "tagsByResource": "[steps('section_tags').tagsByResource]" } } } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/mainTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/mainTemplate.json index d0560de7c..32cf58e1b 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/mainTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/mainTemplate.json @@ -15,25 +15,7 @@ "metadata": { "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." } - }, - "aadsPortNumber": { - "defaultValue": "636", - "type": "string", - "metadata": { - "description": "Accessible port of the LDAP server." - } - }, - "aadsPublicIP": { - "defaultValue": "", - "type": "string" - }, - "aadsServerHost": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "The LDAP server host." - } - }, + }, "adminPasswordOrKey": { "type": "securestring", "metadata": { @@ -47,11 +29,11 @@ "description": "User name for the Virtual Machine." } }, - "adminVMName": { - "defaultValue": "adminVM", + "adminVMNamePrefix": { + "defaultValue": "admin", "type": "string", "metadata": { - "description": "Admin Server hosting VM name." + "description": "Admin Server hosting VM name prefix." } }, "appGatewayCertificateOption": { @@ -62,17 +44,14 @@ }, "allowedValues": [ "haveCert", - "haveKeyVault", "generateCert" ] }, - "appGatewayIdentity": { - "type": "Object", - "defaultValue": { - "type": "UserAssigned", - "userAssignedIdentities": { - "/subscriptions/subscriptionId/resourceGroups/TestResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/TestUserIdentity1": {} - } + "appGatewaySSLBackendCertData": { + "defaultValue": "", + "type": "securestring", + "metadata": { + "description": "The one-line, base64 string of the SSL backend certificate data." } }, "appGatewaySSLCertData": { @@ -107,6 +86,20 @@ "description": "One of the supported database types" } }, + "dbGlobalTranPro": { + "defaultValue": "OnePhaseCommit", + "type": "string", + "metadata": { + "description": "Determines the transaction protocol (global transaction processing behavior) for the data source." + } + }, + "dbIdentity": { + "defaultValue": {}, + "type": "object", + "metadata": { + "description": "Managed identity that has access to the data source." + } + }, "dbPassword": { "defaultValue": "", "type": "securestring", @@ -150,15 +143,6 @@ "description": "DNS for ApplicationGateway" } }, - "dnszoneIdentity": { - "type": "Object", - "defaultValue": { - "type": "UserAssigned", - "userAssignedIdentities": { - "/subscriptions/subscriptionId/resourceGroups/TestResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/TestUserIdentity1": {} - } - } - }, "dnszoneName": { "defaultValue": "contoso.xyz", "type": "string", @@ -187,34 +171,6 @@ "description": "Specify a label used to generate subdomain of Application Gateway. The final subdomain name will be label.dnszoneName, e.g. applications.contoso.xyz" } }, - "elasticsearchEndpoint": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Endpoint of the Elasticsearch instance." - } - }, - "elasticsearchPassword": { - "type": "securestring", - "defaultValue": "[newGuid()]", - "metadata": { - "description": "The credentials to distribute message to Elasticsearch instance with REST API." - } - }, - "elasticsearchUserName": { - "type": "string", - "defaultValue": "elastic", - "metadata": { - "description": "The credentials to distribute message to Elasticsearch instance with REST API." - } - }, - "enableAAD": { - "defaultValue": false, - "type": "bool", - "metadata": { - "description": "Bool value, if it's set to true, will enable Azure Active Directory after WebLogic Server starts." - } - }, "enableAppGateway": { "defaultValue": false, "type": "bool", @@ -236,6 +192,13 @@ "description": "Specifies whether Local Storage is enabled for the Coherence*Web cluster tier." } }, + "enableCookieBasedAffinity": { + "defaultValue": true, + "type": "bool", + "metadata": { + "description": "true to enable cookie based affinity." + } + }, "enableDB": { "defaultValue": false, "type": "bool", @@ -250,11 +213,11 @@ "description": "If true, use the supplied parameters to configure custome DNS." } }, - "enableELK": { + "enablePswlessConnection": { "defaultValue": false, "type": "bool", "metadata": { - "description": "If true, use the supplied parameters to distribute WebLogic Server logs to the Elasticsearch instance." + "description": "True to enable passwordless JDBC connection." } }, "gatewayPublicIPAddressName": { @@ -265,9 +228,13 @@ } }, "guidValue": { - "type": "string", - "defaultValue": "[newGuid()]" - }, + "type": "string", + "defaultValue": "[newGuid()]" + }, + "guidTag": { + "type": "string", + "defaultValue": "[newGuid()]" + }, "hasDNSZones": { "type": "bool", "defaultValue": false, @@ -282,20 +249,6 @@ "description": "JNDI Name for JDBC Datasource" } }, - "keyVaultName": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "KeyVault Name" - } - }, - "keyVaultResourceGroup": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "Resource group name in current subscription containing the KeyVault" - } - }, "keyVaultSku": { "defaultValue": "Standard", "type": "string", @@ -303,20 +256,6 @@ "description": "Price tier for Key Vault." } }, - "keyVaultSSLCertDataSecretName": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "The name of the secret in the specified KeyVault whose value is the SSL Certificate Data" - } - }, - "keyVaultSSLCertPasswordSecretName": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "The name of the secret in the specified KeyVault whose value is the password for the SSL Certificate" - } - }, "location": { "defaultValue": "[resourceGroup().location]", "type": "string", @@ -324,14 +263,6 @@ "description": "Location for all resources." } }, - "logsToIntegrate": { - "type": "array", - "defaultValue": [ "HTTPAccessLog", "ServerLog", "DomainLog", "DataSourceLog", "StandardErrorAndOutput", "NodeManagerLog" ], - "allowedValues": [ "HTTPAccessLog", "ServerLog", "DomainLog", "DataSourceLog", "StandardErrorAndOutput", "NodeManagerLog" ], - "metadata": { - "description": "Specify the expeted logs to integrate, you must input at least one log." - } - }, "managedServerPrefix": { "defaultValue": "msp", "type": "string", @@ -366,28 +297,32 @@ }, "skuUrnVersion": { "type": "string", - "defaultValue": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "defaultValue": "owls-141200-jdk21-ol94;Oracle:weblogic-141200-jdk21-ol94:owls-141200-jdk21-ol94;latest", "allowedValues": [ - "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest", - "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest", - "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest", - "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest", - "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" + "owls-141200-jdk21-ol94;Oracle:weblogic-141200-jdk21-ol94:owls-141200-jdk21-ol94;latest", + "owls-141200-jdk21-ol810;Oracle:weblogic-141200-jdk21-ol810:owls-141200-jdk21-ol810;latest", + "owls-141200-jdk17-ol94;Oracle:weblogic-141200-jdk17-ol94:owls-141200-jdk17-ol94;latest", + "owls-141200-jdk17-ol810;Oracle:weblogic-141200-jdk17-ol810:owls-141200-jdk17-ol810;latest", + "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", + "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest", + "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest", + "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest", + "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest", + "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest", + "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest", + "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest" ], "metadata": { "description": "The Oracle Linux image with Weblogic and Java preinstalled. Semicolon separated string of Sku, URN, and Version" } }, - "sslConfigurationAccessOption": { - "type": "string", + "tagsByResource": { + "type": "object", + "defaultValue": {}, "metadata": { - "description": "Options to provide required configuration for SSL configuration" - }, - "allowedValues": [ - "uploadConfig", - "keyVaultStoredConfig" - ], - "defaultValue": "keyVaultStoredConfig" + "description": "${label.tagsLabel}" + } }, "usePreviewImage": { "type": "bool", @@ -403,14 +338,7 @@ "description": "Bool value, if it's set to true, a system assigned managed identity will to be created for the VM(s)" } }, - "utcNow": { - "type": "string", - "defaultValue": "[utcNow()]", - "metadata": { - "description": "Returns the current (UTC) datetime value in the ISO 8601 format." - } - }, - "vmSizeSelect": { + "vmSize": { "defaultValue": "Standard_A3", "type": "string", "metadata": { @@ -424,53 +352,73 @@ "description": "Select appropriate VM Size for Coherence" } }, - "wlsDomainName": { - "defaultValue": "wlsd", + "virtualNetworkNewOrExisting": { "type": "string", + "defaultValue": "new", + "allowedValues": [ + "new", + "existing" + ], "metadata": { - "description": "Provide Weblogic domain name" + "description": "Specify whether to create a new or existing virtual network for the VM." } }, - "wlsLDAPGroupBaseDN": { - "defaultValue": "null", + "virtualNetworkName": { "type": "string", + "defaultValue": "[concat('wlscluster-vnet-', uniqueString(utcNow()))]", "metadata": { - "description": "The base distinguished name (DN) of the tree in the LDAP directory that contains groups." + "description": "Name of the existing or new VNET" } }, - "wlsLDAPPrincipal": { - "defaultValue": "null", + "virtualNetworkResourceGroupName": { "type": "string", + "defaultValue": "[resourceGroup().name]", "metadata": { - "description": "The Distinguished Name (DN) of the LDAP user that WebLogic Server should use to connect to the LDAP server." + "description": "Resource group of Virtual network" } }, - "wlsLDAPPrincipalPassword": { - "defaultValue": "", - "type": "securestring", + "addressPrefixes": { + "type": "array", + "defaultValue": [ + "10.0.0.0/16" + ], "metadata": { - "description": "The credential (usually a password) used to connect to the LDAP server." + "description": "Address prefix of the VNET." } }, - "wlsLDAPProviderName": { - "defaultValue": "AzureActiveDirectoryProvider", + "subnetName": { "type": "string", + "defaultValue": "wls-subnet", "metadata": { - "description": "The value used for creating authentication provider name of WebLogic Server." + "description": "Name of the existing or new Subnet" } }, - "wlsLDAPSSLCertificate": { - "defaultValue": "null", + "subnetPrefix": { "type": "string", + "defaultValue": "10.0.0.0/24", "metadata": { - "description": "Client certificate that will be imported to trust store of SSL." + "description": "Address prefix of the subnet" } }, - "wlsLDAPUserBaseDN": { - "defaultValue": "null", + "subnetForAppGateway": { "type": "string", + "defaultValue": "appgateway-subnet", "metadata": { - "description": "The base distinguished name (DN) of the tree in the LDAP directory that contains users." + "description": "Name of the existing or new Subnet for Application Gateway" + } + }, + "subnetPrefixForAppGateway": { + "type": "string", + "defaultValue": "10.0.1.0/24", + "metadata": { + "description": "Address prefix of the subnet for Application Gateway" + } + }, + "wlsDomainName": { + "defaultValue": "wlsd", + "type": "string", + "metadata": { + "description": "Provide Weblogic domain name" } }, "wlsUserName": { @@ -487,88 +435,18 @@ } }, "enableHTTPAdminListenPort": { - "defaultValue": true, - "type": "bool", - "metadata": { - "description": "Boolean value indicating, if WebLogic Admin Server HTTP Listen Port is enabled or not" - } - }, - "enableCustomSSL":{ - "defaultValue":false, + "defaultValue": true, "type": "bool", "metadata": { - "description": "Boolean value indicating, if custom SSL is enabled or not" + "description": "Boolean value indicating, if WebLogic Admin Server HTTP Listen Port is enabled or not" } - }, - "adminSSLKeyVaultResourceGroup": { - "defaultValue": "", - "type": "string", + }, + "enableCustomSSL": { + "defaultValue": false, + "type": "bool", "metadata": { - "description": "Resource group name in current subscription containing the KeyVault for SSL Configuration of WebLogic Administration Server" + "description": "Boolean value indicating, if custom SSL is enabled or not" } - }, - "adminSSLKeyVaultName": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "KeyVault Name for SSL Configuration of WebLogic Administration Server" - } - }, - "keyVaultCustomIdentityKeyStoreDataSecretName":{ - "type": "string", - "metadata": { - "description": "Secret name in KeyVault containing Weblogic Custom Identity Keystore Data" - }, - "defaultValue": "CustomIdentityKeyStoreDataSecret" - }, - "keyVaultCustomIdentityKeyStorePassPhraseSecretName":{ - "type": "string", - "metadata": { - "description": "Secret name in KeyVault containing Weblogic Custom Identity Keystore Passphrase" - }, - "defaultValue": "CustomIdentityKeyStorePassPhraseSecret" - }, - "keyVaultCustomIdentityKeyStoreType":{ - "type": "string", - "metadata": { - "description": "Weblogic Custom Identity Keystore Type" - }, - "defaultValue": "JKS" - }, - "keyVaultCustomTrustKeyStoreDataSecretName":{ - "type": "string", - "metadata": { - "description": "Secret name in KeyVault containing Weblogic Custom Trust Store Data" - }, - "defaultValue": "CustomTrustStoreDataSecret" - }, - "keyVaultCustomTrustKeyStorePassPhraseSecretName":{ - "type": "string", - "metadata": { - "description": "Secret name in KeyVault containing Weblogic Custom Trust Store Passphrase" - }, - "defaultValue": "CustomTrustStorePassPhraseSecret" - }, - "keyVaultCustomTrustKeyStoreType":{ - "type": "string", - "metadata": { - "description": "Weblogic Custom Trust Store Type" - }, - "defaultValue": "JKS" - }, - "keyVaultPrivateKeyAliasSecretName":{ - "type": "string", - "metadata": { - "description": "Secret name in KeyVault containing Weblogic Server Private Key Alias" - }, - "defaultValue": "ServerPrivateKeyAlias" - }, - "keyVaultPrivateKeyPassPhraseSecretName":{ - "type": "string", - "metadata": { - "description": "Secret name in KeyVault containing Weblogic Server Private KeyPassPhrase" - }, - "defaultValue": "ServerPrivateKeyPassPhraseSecret" }, "uploadedCustomIdentityKeyStoreData": { "type": "string", @@ -625,60 +503,101 @@ "description": "Password of the private key" }, "defaultValue": "" - }, - "enabledForTemplateDeployment": { - "type": "bool", - "metadata": { - "description": "Property to specify whether Azure Resource Manager is permitted to retrieve secrets from the key vault." - }, - "defaultValue": true } }, "variables": { - "const_currentSubscription": "[subscription().subscriptionId]", - "const_appGatewaySSLCertOptionHaveCert": "haveCert", - "const_appGatewaySSLCertOptionHaveKeyVault": "haveKeyVault", - "const_sslConfigurationAccessOptionUploadConfig": "uploadConfig", - "const_sslConfigurationAccessOptionKeyVaultStoredConfig": "keyVaultStoredConfig", - "const_azureSubjectName": "[format('{0}.{1}.{2}', variables('name_domainLabelforApplicationGateway'), parameters('location'),'.cloudapp.azure.com')]", - "const_guidValue": "[parameters('guidValue')]", - "name_aadLinkedTemplateName": "aadNestedTemplate.json", - "name_appGatewayConnector": "_keyvaultAppGatewayConnectorTemplate.json", + "const_appGatewaySSLCertOptionGenerateCert": "generateCert", + "const_azureSubjectName": "[format('{0}.{1}.{2}', variables('name_domainLabelforApplicationGateway'), parameters('location'),'cloudapp.azure.com')]", + "const_globalResourceNameSuffix": "[uniqueString(parameters('guidValue'))]", + "const_guidTag": "[uniqueString(parameters('guidTag'))]", + "const_vmSize": "[parameters('vmSize')]", + "const_vmSizeCoherence": "[parameters('vmSizeSelectForCoherence')]", + "name_adminVM": "[concat(parameters('adminVMNamePrefix'), variables('const_globalResourceNameSuffix'), 'VM')]", + "name_appGatewayConnector": "_appGatewayConnectorTemplate.json", "name_clusterLinkedTemplateName": "clusterTemplate.json", "name_clusterCustomSSLLinkedTemplateName": "clusterCustomSSLTemplate.json", "name_coherenceTemplateName": "coherenceTemplate.json", "name_dbLinkedTemplateName": "dbTemplate.json", - "name_dnsNameforApplicationGateway": "[concat(parameters('dnsNameforApplicationGateway'), take(replace(variables('const_guidValue'),'-',''),6))]", + "name_dnsNameforApplicationGateway": "[concat(parameters('dnsNameforApplicationGateway'), take(variables('const_globalResourceNameSuffix'), 6))]", "name_dnszonesLinkedTemplateName": "dnszonesTemplate.json", "name_domainLabelforApplicationGateway": "[take(concat(variables('name_dnsNameforApplicationGateway'),'-',toLower(resourceGroup().name),'-',toLower(parameters('wlsDomainName'))),63)]", - "name_elkLinkedTemplateName": "elkNestedTemplate.json", - "name_keyVaultLinkedTemplateName": "_keyvaultAdapterTemplate.json", + "name_keyVaultLinkedTemplateName": "_keyvaultWithNewCertTemplate.json", + "name_postDeploymentUAMIRolesTemplate" : "postDeploymentUAMIRolesTemplate.json", + "name_postDeploymentTemplate": "postDeploymentTemplate.json", + "name_networkSecurityGroup": "[concat(parameters('dnsLabelPrefix'), '-nsg-', variables('const_globalResourceNameSuffix'))]", "name_nsgLinkedTemplateName": "nsgNestedTemplate.json", + "name_managedVMNamePrefix": "[concat(parameters('managedServerPrefix'), variables('const_globalResourceNameSuffix'))]", "clusterTemplateRef": "[concat('cluster',if(parameters('enableCustomSSL'),'CustomSSL',''),'LinkedTemplate')]", "name_clusterTemplate": "clusterLinkedTemplate", "name_clusterCustomSSLTemplate": "clusterCustomSSLLinkedTemplate", - "name_sslKeyVaultLinkedTemplateName": "_keyvaultSSLConfigTemplate.json", - "name_keyVaultName": "[take(concat('wls-kv', uniqueString(parameters('utcNow'))), 24)]" + "name_uamiForPostDeploymentScript" : "uamiForPostDeploymentScript", + "name_keyVaultName": "[concat('wls-kv-', variables('const_globalResourceNameSuffix'))]", + "name_secretName": "mySelfSignedCertificate", + // If adding a new resource, add the resource identifier to the array below + // Also modify createUIDefinition.json to include the new resource + "obj_tagsByResources": { + "${identifier.applicationGateways}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.applicationGateways}')]", + "${identifier.availabilitySets}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.availabilitySets}')]", + "${identifier.dnszones}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.dnszones}')]", + "${identifier.networkInterfaces}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.networkInterfaces}')]", + "${identifier.networkSecurityGroups}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.networkSecurityGroups}')]", + "${identifier.publicIPAddresses}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.publicIPAddresses}')]", + "${identifier.privateEndpoints}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.privateEndpoints}')]", + "${identifier.storageAccounts}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.storageAccounts}')]", + "${identifier.vaults}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.vaults}')]", + "${identifier.virtualNetworks}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.virtualNetworks}')]", + "${identifier.virtualMachines}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.virtualMachines}')]", + "${identifier.virtualMachinesExtensions}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.virtualMachinesExtensions}')]", + "${identifier.deploymentScripts}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.deploymentScripts}')]", + "${identifier.userAssignedIdentities}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.userAssignedIdentities}')]", + "${identifier.resourcesDeployment}": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.resourcesDeployment}')]" + } }, + "functions": [ + { + // This same function is defined in the mainTemplate.json for every other offer. + // Please ensure any changes are applied in all the other places. + "namespace": "funcTags", + "members": { + "tagsFilter": { + "parameters": [ + { + "name": "tagsByResource", + "type": "object" + }, + { + "name": "resourceIdentifier", + "type": "string" + } + ], + "output": { + "type": "object", + "value": "[if(contains(parameters('tagsByResource'), parameters('resourceIdentifier')), parameters('tagsByResource')[parameters('resourceIdentifier')], json('{}'))]" + } + } + } + } + ], "resources": [ { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${cluster.start}", "type": "Microsoft.Resources/deployments", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", "properties": { "mode": "Incremental", "template": { "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", - "resources": [ - ] + "resources": [] } } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "[variables('name_clusterTemplate')]", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", "condition": "[not(parameters('enableCustomSSL'))]", "properties": { "mode": "Incremental", @@ -693,18 +612,30 @@ "_artifactsLocationSasToken": { "value": "[parameters('_artifactsLocationSasToken')]" }, + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" + }, + "const_guidTag":{ + "value": "[variables('const_guidTag')]" + }, "adminPasswordOrKey": { "value": "[parameters('adminPasswordOrKey')]" }, "adminUsername": { "value": "[parameters('adminUsername')]" }, + "adminVMNamePrefix": { + "value": "[parameters('adminVMNamePrefix')]" + }, "adminVMName": { - "value": "[parameters('adminVMName')]" + "value": "[variables('name_adminVM')]" }, "authenticationType": { "value": "[parameters('authenticationType')]" }, + "addressPrefixes": { + "value": "[parameters('addressPrefixes')]" + }, "dnsLabelPrefix": { "value": "[parameters('dnsLabelPrefix')]" }, @@ -714,23 +645,53 @@ "managedServerPrefix": { "value": "[parameters('managedServerPrefix')]" }, + "managedVMNamePrefix": { + "value": "[variables('name_managedVMNamePrefix')]" + }, "numberOfInstances": { "value": "[parameters('numberOfInstances')]" }, + "nsgName": { + "value": "[variables('name_networkSecurityGroup')]" + }, "portsToExpose": { "value": "[parameters('portsToExpose')]" }, "skuUrnVersion": { "value": "[parameters('skuUrnVersion')]" }, + "subnetName": { + "value": "[parameters('subnetName')]" + }, + "subnetPrefix": { + "value": "[parameters('subnetPrefix')]" + }, + "subnetForAppGateway": { + "value": "[parameters('subnetForAppGateway')]" + }, + "subnetPrefixForAppGateway": { + "value": "[parameters('subnetPrefixForAppGateway')]" + }, + "tagsByResource": { + "value": "[variables('obj_tagsByResources')]" + }, "usePreviewImage": { "value": "[parameters('usePreviewImage')]" }, "useSystemAssignedManagedIdentity": { "value": "[parameters('useSystemAssignedManagedIdentity')]" }, - "vmSizeSelect": { - "value": "[parameters('vmSizeSelect')]" + "vmSize": { + "value": "[variables('const_vmSize')]" + }, + "virtualNetworkNewOrExisting": { + "value": "[parameters('virtualNetworkNewOrExisting')]" + }, + "virtualNetworkName": { + "value": "[parameters('virtualNetworkName')]" + }, + "virtualNetworkResourceGroupName": { + "value": "[parameters('virtualNetworkResourceGroupName')]" }, "wlsDomainName": { "value": "[parameters('wlsDomainName')]" @@ -741,60 +702,25 @@ "wlsUserName": { "value": "[parameters('wlsUserName')]" }, - "enableHTTPAdminListenPort":{ + "enableAppGateway": { + "value": "[parameters('enableAppGateway')]" + }, + "enableHTTPAdminListenPort": { "value": "[parameters('enableHTTPAdminListenPort')]" + }, + "enableDNSConfiguration": { + "value": "[parameters('enableDNSConfiguration')]" + }, + "customDNSNameForAdminServer": { + "value": "[if(parameters('enableDNSConfiguration'), format('{0}.{1}', parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')),'')]" } } } }, - { - "name": "sslKeyVaultNestedTemplate", - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "condition": "[and(parameters('enableCustomSSL'), equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionUploadConfig')))]", - "properties": { - "mode": "Incremental", - "templateLink": { - "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_sslKeyVaultLinkedTemplateName')))]", - "contentVersion": "1.0.0.0" - }, - "parameters": { - "uploadedCustomIdentityKeyStoreData": { - "value": "[parameters('uploadedCustomIdentityKeyStoreData')]" - }, - "uploadedCustomIdentityKeyStorePassphrase": { - "value": "[parameters('uploadedCustomIdentityKeyStorePassphrase')]" - }, - "uploadedCustomTrustKeyStoreData": { - "value": "[parameters('uploadedCustomTrustKeyStoreData')]" - }, - "uploadedCustomTrustKeyStorePassPhrase": { - "value": "[parameters('uploadedCustomTrustKeyStorePassPhrase')]" - }, - "uploadedPrivateKeyAlias": { - "value": "[parameters('uploadedPrivateKeyAlias')]" - }, - "uploadedPrivateKeyPassPhrase": { - "value": "[parameters('uploadedPrivateKeyPassPhrase')]" - }, - "enabledForTemplateDeployment": { - "value": "[parameters('enabledForTemplateDeployment')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "sku": { - "value": "[parameters('keyVaultSku')]" - }, - "keyVaultName": { - "value": "[variables('name_keyVaultName')]" - } - } - } - }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", "name": "[variables('name_clusterCustomSSLTemplate')]", "condition": "[parameters('enableCustomSSL')]", "properties": { @@ -810,18 +736,30 @@ "_artifactsLocationSasToken": { "value": "[parameters('_artifactsLocationSasToken')]" }, + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" + }, + "const_guidTag":{ + "value": "[variables('const_guidTag')]" + }, "adminPasswordOrKey": { "value": "[parameters('adminPasswordOrKey')]" }, "adminUsername": { "value": "[parameters('adminUsername')]" }, + "adminVMNamePrefix": { + "value": "[parameters('adminVMNamePrefix')]" + }, "adminVMName": { - "value": "[parameters('adminVMName')]" + "value": "[variables('name_adminVM')]" }, "authenticationType": { "value": "[parameters('authenticationType')]" }, + "addressPrefixes": { + "value": "[parameters('addressPrefixes')]" + }, "dnsLabelPrefix": { "value": "[parameters('dnsLabelPrefix')]" }, @@ -831,23 +769,53 @@ "managedServerPrefix": { "value": "[parameters('managedServerPrefix')]" }, + "managedVMNamePrefix": { + "value": "[variables('name_managedVMNamePrefix')]" + }, "numberOfInstances": { "value": "[parameters('numberOfInstances')]" }, + "nsgName": { + "value": "[variables('name_networkSecurityGroup')]" + }, "portsToExpose": { "value": "[parameters('portsToExpose')]" }, "skuUrnVersion": { "value": "[parameters('skuUrnVersion')]" }, + "subnetName": { + "value": "[parameters('subnetName')]" + }, + "subnetPrefix": { + "value": "[parameters('subnetPrefix')]" + }, + "subnetForAppGateway": { + "value": "[parameters('subnetForAppGateway')]" + }, + "subnetPrefixForAppGateway": { + "value": "[parameters('subnetPrefixForAppGateway')]" + }, + "tagsByResource": { + "value": "[variables('obj_tagsByResources')]" + }, "usePreviewImage": { "value": "[parameters('usePreviewImage')]" }, "useSystemAssignedManagedIdentity": { "value": "[parameters('useSystemAssignedManagedIdentity')]" }, - "vmSizeSelect": { - "value": "[parameters('vmSizeSelect')]" + "vmSize": { + "value": "[variables('const_vmSize')]" + }, + "virtualNetworkNewOrExisting": { + "value": "[parameters('virtualNetworkNewOrExisting')]" + }, + "virtualNetworkName": { + "value": "[parameters('virtualNetworkName')]" + }, + "virtualNetworkResourceGroupName": { + "value": "[parameters('virtualNetworkResourceGroupName')]" }, "wlsDomainName": { "value": "[parameters('wlsDomainName')]" @@ -858,80 +826,56 @@ "wlsUserName": { "value": "[parameters('wlsUserName')]" }, - "enableHTTPAdminListenPort":{ + "enableAppGateway": { + "value": "[parameters('enableAppGateway')]" + }, + "enableHTTPAdminListenPort": { "value": "[parameters('enableHTTPAdminListenPort')]" }, - "enableCustomSSL":{ - "value": "[parameters('enableCustomSSL')]" + "enableDNSConfiguration": { + "value": "[parameters('enableDNSConfiguration')]" }, - "keyVaultCustomIdentityKeyStoreData": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomIdentityKeyStoreDataSecretName'),reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.customIdentityKeyStoreDataSecretName.value)]" - } + "customDNSNameForAdminServer": { + "value": "[if(parameters('enableDNSConfiguration'), format('{0}.{1}', parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')),'')]" }, - "keyVaultCustomIdentityKeyStorePassPhrase": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomIdentityKeyStorePassPhraseSecretName'), reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.customIdentityKeyStorePassPhraseSecretName.value)]" - } + "enableCustomSSL": { + "value": "[parameters('enableCustomSSL')]" }, - "keyVaultCustomIdentityKeyStoreType":{ - "value": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomIdentityKeyStoreType'), parameters('uploadedCustomIdentityKeyStoreType'))]" + "sslCustomIdentityKeyStoreData": { + "value": "[parameters('uploadedCustomIdentityKeyStoreData')]" }, - "keyVaultCustomTrustKeyStoreData": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStoreDataSecretName'), reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.customTrustKeyStoretDataSecretName.value)]" - } - }, - "keyVaultCustomTrustKeyStorePassPhrase": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStorePassPhraseSecretName'), reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.customTrustKeyStorePassPhraseSecretName.value)]" - } - }, - "keyVaultCustomTrustKeyStoreType":{ - "value": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStoreType'), parameters('uploadedCustomTrustKeyStoreType'))]" - }, - "keyVaultPrivateKeyAlias":{ - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultPrivateKeyAliasSecretName'), reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.privateKeyAliasSecretName.value)]" - } - }, - "keyVaultPrivateKeyPassPhrase": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultPrivateKeyPassPhraseSecretName'), reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.privateKeyPassPhraseSecretName.value)]" - } + "sslCustomIdentityKeyStorePassPhrase": { + "value": "[parameters('uploadedCustomIdentityKeyStorePassphrase')]" + }, + "sslCustomIdentityKeyStoreType": { + "value": "[parameters('uploadedCustomIdentityKeyStoreType')]" + }, + "sslCustomTrustKeyStoreData": { + "value": "[parameters('uploadedCustomTrustKeyStoreData')]" + }, + "sslCustomTrustKeyStorePassPhrase": { + "value": "[parameters('uploadedCustomTrustKeyStorePassPhrase')]" + }, + "sslCustomTrustKeyStoreType": { + "value": "[parameters('uploadedCustomTrustKeyStoreType')]" + }, + "sslPrivateKeyAlias": { + "value": "[parameters('uploadedPrivateKeyAlias')]" + }, + "sslPrivateKeyPassPhrase": { + "value": "[parameters('uploadedPrivateKeyPassPhrase')]" } } - }, - "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'sslKeyVaultNestedTemplate')]" - ] + } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "keyVaultLinkedTemplate", - "condition": "[and(parameters('enableAppGateway'), not(equals(parameters('appGatewayCertificateOption'), variables('const_appGatewaySSLCertOptionHaveKeyVault'))))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", + "name": "keyVaultwithSelfSignedAppGatewaySSLCert", + "condition": "[and(parameters('enableAppGateway'), equals(parameters('appGatewayCertificateOption'), variables('const_appGatewaySSLCertOptionGenerateCert')))]", "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', variables('clusterTemplateRef'))]", - "[resourceId('Microsoft.Resources/deployments', 'sslKeyVaultNestedTemplate')]" + "[resourceId('Microsoft.Resources/deployments', variables('clusterTemplateRef'))]" ], "properties": { "mode": "Incremental", @@ -940,42 +884,35 @@ "contentVersion": "1.0.0.0" }, "parameters": { - "_artifactsLocation": { - "value": "[parameters('_artifactsLocation')]" - }, - "_artifactsLocationSasToken": { - "value": "[parameters('_artifactsLocationSasToken')]" + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" }, - "certificateDataValue": { - "value": "[parameters('appGatewaySSLCertData')]" - }, - "certificatePasswordValue": { - "value": "[parameters('appGatewaySSLCertPassword')]" - }, - "identity": { - "value": "[parameters('appGatewayIdentity')]" + "keyVaultName": { + "value": "[variables('name_keyVaultName')]" }, "location": { "value": "[parameters('location')]" }, + "secretName": { + "value": "[variables('name_secretName')]" + }, "sku": { "value": "[parameters('keyVaultSku')]" }, "subjectName": { "value": "[format('CN={0}', if(parameters('enableDNSConfiguration'), format('{0}.{1}', parameters('dnsNameforApplicationGateway'), parameters('dnszoneName')), variables('const_azureSubjectName')))]" }, - "useExistingAppGatewaySSLCertificate": { - "value": "[if(equals(parameters('appGatewayCertificateOption'),variables('const_appGatewaySSLCertOptionHaveCert')), true(), false())]" - }, - "keyVaultName": { - "value": "[variables('name_keyVaultName')]" + "tagsByResource": { + "value": "[variables('obj_tagsByResources')]" } } } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", "name": "networkSecurityLinkedTemplate", "properties": { "mode": "Incremental", @@ -985,7 +922,7 @@ }, "parameters": { "networkSecurityGroupName": { - "value": "[concat(parameters('dnsLabelPrefix'), '-nsg')]" + "value": "[variables('name_networkSecurityGroup')]" }, "denyPublicTrafficForAdminServer": { "value": "[parameters('denyPublicTrafficForAdminServer')]" @@ -1004,8 +941,9 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "keyVaultLinkedAppGatewayTemplate", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", + "name": "appGatewayLinkedTemplate", "condition": "[parameters('enableAppGateway')]", "properties": { "mode": "Incremental", @@ -1021,46 +959,43 @@ "value": "[parameters('_artifactsLocationSasToken')]" }, "adminVMName": { - "value": "[parameters('adminVMName')]" + "value": "[variables('name_adminVM')]" + }, + "appGatewayName": { + "value": "[concat(parameters('dnsLabelPrefix'), '-agw-', variables('const_globalResourceNameSuffix'))]" }, "appGatewayCertificateOption": { "value": "[parameters('appGatewayCertificateOption')]" }, + "appGatewaySSLBackendCertData": { + "value": "[parameters('appGatewaySSLBackendCertData')]" + }, + "autoGeneratedSSLCertKeyVaultName": { + "value": "[if(equals(parameters('appGatewayCertificateOption'), variables('const_appGatewaySSLCertOptionGenerateCert')), reference('keyVaultwithSelfSignedAppGatewaySSLCert', '${azure.apiVersionForDeployment}').outputs.keyvaultName.value, '')]" + }, + "autoGeneratedSSLCertSecretName": { + "value": "[if(equals(parameters('appGatewayCertificateOption'), variables('const_appGatewaySSLCertOptionGenerateCert')), reference('keyVaultwithSelfSignedAppGatewaySSLCert', '${azure.apiVersionForDeployment}').outputs.secretName.value, '')]" + }, "customDomainNameforApplicationGateway": { "value": "[format('{0}.{1}', parameters('dnszoneAppGatewayLabel'), parameters('dnszoneName'))]" }, "domainLabelforApplicationGateway": { "value": "[variables('name_domainLabelforApplicationGateway')]" }, - "gatewayPublicIPAddressName": { - "value": "[parameters('gatewayPublicIPAddressName')]" - }, - "keyVaultName": { - "value": "[parameters('keyVaultName')]" - }, - "keyVaultNamefromDeploymentOutput": { - "value": "[if(and(parameters('enableAppGateway'),not(equals(parameters('appGatewayCertificateOption'), variables('const_appGatewaySSLCertOptionHaveKeyVault')))),reference('keyVaultLinkedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value,'')]" - }, - "keyVaultResourceGroup": { - "value": "[parameters('keyVaultResourceGroup')]" - }, - "keyVaultSSLCertDataSecretName": { - "value": "[parameters('keyVaultSSLCertDataSecretName')]" - }, - "keyVaultSSLCertDataSecretNamefromDeploymentOutput": { - "value": "[if(and(parameters('enableAppGateway'),not(equals(parameters('appGatewayCertificateOption'), variables('const_appGatewaySSLCertOptionHaveKeyVault')))),reference('keyVaultLinkedTemplate', '${azure.apiVersion}').outputs.sslCertDataSecretName.value,'')]" + "enableCustomSSL": { + "value": "[parameters('enableCustomSSL')]" }, - "keyVaultSSLCertPasswordSecretName": { - "value": "[parameters('keyVaultSSLCertPasswordSecretName')]" + "enableCookieBasedAffinity": { + "value": "[parameters('enableCookieBasedAffinity')]" }, - "keyVaultSSLCertPasswordSecretNamefromDeploymentOutput": { - "value": "[if(and(parameters('enableAppGateway'),not(equals(parameters('appGatewayCertificateOption'), variables('const_appGatewaySSLCertOptionHaveKeyVault')))),reference('keyVaultLinkedTemplate', '${azure.apiVersion}').outputs.sslCertPwdSecretName.value,'')]" + "gatewayPublicIPAddressName": { + "value": "[concat(parameters('gatewayPublicIPAddressName'), variables('const_globalResourceNameSuffix'))]" }, "location": { "value": "[parameters('location')]" }, - "managedServerPrefix": { - "value": "[parameters('managedServerPrefix')]" + "managedVMNamePrefix": { + "value": "[variables('name_managedVMNamePrefix')]" }, "numberOfInstances": { "value": "[parameters('numberOfInstances')]" @@ -1068,6 +1003,27 @@ "overrideHostName": { "value": "[parameters('enableDNSConfiguration')]" }, + "sslCertData": { + "value": "[parameters('appGatewaySSLCertData')]" + }, + "sslCertPswData": { + "value": "[parameters('appGatewaySSLCertPassword')]" + }, + "tagsByResource": { + "value": "[variables('obj_tagsByResources')]" + }, + "virtualNetworkNewOrExisting": { + "value": "[parameters('virtualNetworkNewOrExisting')]" + }, + "virtualNetworkResourceGroupName": { + "value": "[parameters('virtualNetworkResourceGroupName')]" + }, + "virtualNetworkName": { + "value": "[parameters('virtualNetworkName')]" + }, + "subnetForAppGateway": { + "value": "[parameters('subnetForAppGateway')]" + }, "wlsDomainName": { "value": "[parameters('wlsDomainName')]" }, @@ -1080,16 +1036,18 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'keyVaultLinkedTemplate')]" + "[resourceId('Microsoft.Resources/deployments', 'keyVaultwithSelfSignedAppGatewaySSLCert')]", + "[resourceId('Microsoft.Resources/deployments', variables('clusterTemplateRef'))]" ] }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", "name": "dnszonesLinkedTemplate", "condition": "[parameters('enableDNSConfiguration')]", "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'keyVaultLinkedAppGatewayTemplate')]" + "[resourceId('Microsoft.Resources/deployments', 'appGatewayLinkedTemplate')]" ], "properties": { "mode": "Incremental", @@ -1104,13 +1062,16 @@ "_artifactsLocationSasToken": { "value": "[parameters('_artifactsLocationSasToken')]" }, + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" + }, "dnszonesARecordSetNames": { "value": [ "[parameters('dnszoneAdminConsoleLabel')]" ] }, "dnszonesCNAMEAlias": { - "value": "[if(parameters('enableAppGateway'), createArray(reference('keyVaultLinkedAppGatewayTemplate', '${azure.apiVersion}').outputs.appGatewayAlias.value), createArray())]" + "value": "[if(parameters('enableAppGateway'), createArray(reference('appGatewayLinkedTemplate', '${azure.apiVersionForDeployment}').outputs.appGatewayAlias.value), createArray())]" }, "dnszonesCNAMERecordSetNames": { "value": "[if(parameters('enableAppGateway'), createArray(parameters('dnszoneAppGatewayLabel')), createArray())]" @@ -1121,9 +1082,6 @@ "hasDNSZones": { "value": "[parameters('hasDNSZones')]" }, - "identity": { - "value": "[parameters('dnszoneIdentity')]" - }, "location": { "value": "[parameters('location')]" }, @@ -1132,16 +1090,19 @@ }, "targetResources": { "value": [ - "[reference(variables('clusterTemplateRef'), '${azure.apiVersion}').outputs._adminPublicIPId.value]" + "[reference(variables('clusterTemplateRef'), '${azure.apiVersionForDeployment}').outputs._adminPublicIPId.value]" ] + }, + "tagsByResource": { + "value": "[variables('obj_tagsByResources')]" } } - } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", "name": "dbLinkedTemplate", "condition": "[parameters('enableDB')]", "dependsOn": [ @@ -1161,11 +1122,17 @@ "value": "[parameters('_artifactsLocationSasToken')]" }, "adminVMName": { - "value": "[parameters('adminVMName')]" + "value": "[variables('name_adminVM')]" }, "databaseType": { "value": "[parameters('databaseType')]" }, + "dbGlobalTranPro": { + "value": "[parameters('dbGlobalTranPro')]" + }, + "dbIdentity": { + "value": "[parameters('dbIdentity')]" + }, "dbPassword": { "value": "[parameters('dbPassword')]" }, @@ -1175,226 +1142,27 @@ "dsConnectionURL": { "value": "[parameters('dsConnectionURL')]" }, + "enablePswlessConnection": { + "value": "[parameters('enablePswlessConnection')]" + }, "jdbcDataSourceName": { "value": "[parameters('jdbcDataSourceName')]" }, "location": { "value": "[parameters('location')]" }, - "wlsPassword": { - "value": "[parameters('wlsPassword')]" - }, - "wlsUserName": { - "value": "[parameters('wlsUserName')]" - } - } - } - }, - { - "name": "aadLinkedTemplate", - "type": "Microsoft.Resources/deployments", - "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'dbLinkedTemplate')]" - ], - "apiVersion": "${azure.apiVersion}", - "condition": "[and(parameters('enableAAD'),not(parameters('enableCustomSSL')))]", - "properties": { - "mode": "Incremental", - "templateLink": { - "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_aadLinkedTemplateName')))]", - "contentVersion": "1.0.0.0" - }, - "parameters": { - "_artifactsLocation": { - "value": "[parameters('_artifactsLocation')]" - }, - "_artifactsLocationSasToken": { - "value": "[parameters('_artifactsLocationSasToken')]" - }, - "aadsPortNumber": { - "value": "[parameters('aadsPortNumber')]" - }, - "aadsPublicIP": { - "value": "[parameters('aadsPublicIP')]" - }, - "aadsServerHost": { - "value": "[parameters('aadsServerHost')]" - }, - "adminVMName": { - "value": "[parameters('adminVMName')]" - }, - "location": { - "value": "[parameters('location')]" - }, "managedServerPrefix": { "value": "[parameters('managedServerPrefix')]" }, - "numberOfInstances": { - "value": "[parameters('numberOfInstances')]" - }, - "wlsDomainName": { - "value": "[parameters('wlsDomainName')]" - }, - "wlsLDAPGroupBaseDN": { - "value": "[parameters('wlsLDAPGroupBaseDN')]" - }, - "wlsLDAPPrincipal": { - "value": "[parameters('wlsLDAPPrincipal')]" - }, - "wlsLDAPPrincipalPassword": { - "value": "[parameters('wlsLDAPPrincipalPassword')]" - }, - "wlsLDAPProviderName": { - "value": "[parameters('wlsLDAPProviderName')]" - }, - "wlsLDAPSSLCertificate": { - "value": "[parameters('wlsLDAPSSLCertificate')]" - }, - "wlsLDAPUserBaseDN": { - "value": "[parameters('wlsLDAPUserBaseDN')]" - }, - "wlsPassword": { - "value": "[parameters('wlsPassword')]" - }, - "wlsUserName": { - "value": "[parameters('wlsUserName')]" - } - } - } - }, - { - "name": "aadLinkedTemplateWithCustomSSL", - "type": "Microsoft.Resources/deployments", - "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'dbLinkedTemplate')]", - "[resourceId('Microsoft.Resources/deployments', 'sslKeyVaultNestedTemplate')]" - ], - "apiVersion": "${azure.apiVersion}", - "condition": "[and(parameters('enableAAD'),parameters('enableCustomSSL'))]", - "properties": { - "mode": "Incremental", - "templateLink": { - "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_aadLinkedTemplateName')))]", - "contentVersion": "1.0.0.0" - }, - "parameters": { - "_artifactsLocation": { - "value": "[parameters('_artifactsLocation')]" - }, - "_artifactsLocationSasToken": { - "value": "[parameters('_artifactsLocationSasToken')]" - }, - "aadsPortNumber": { - "value": "[parameters('aadsPortNumber')]" - }, - "aadsPublicIP": { - "value": "[parameters('aadsPublicIP')]" - }, - "aadsServerHost": { - "value": "[parameters('aadsServerHost')]" - }, - "adminVMName": { - "value": "[parameters('adminVMName')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "managedServerPrefix": { - "value": "[parameters('managedServerPrefix')]" - }, - "numberOfInstances": { - "value": "[parameters('numberOfInstances')]" - }, - "wlsDomainName": { - "value": "[parameters('wlsDomainName')]" - }, - "wlsLDAPGroupBaseDN": { - "value": "[parameters('wlsLDAPGroupBaseDN')]" - }, - "wlsLDAPPrincipal": { - "value": "[parameters('wlsLDAPPrincipal')]" - }, - "wlsLDAPPrincipalPassword": { - "value": "[parameters('wlsLDAPPrincipalPassword')]" - }, - "wlsLDAPProviderName": { - "value": "[parameters('wlsLDAPProviderName')]" - }, - "wlsLDAPSSLCertificate": { - "value": "[parameters('wlsLDAPSSLCertificate')]" - }, - "wlsLDAPUserBaseDN": { - "value": "[parameters('wlsLDAPUserBaseDN')]" - }, - "wlsPassword": { - "value": "[parameters('wlsPassword')]" - }, - "wlsUserName": { - "value": "[parameters('wlsUserName')]" - }, - "enableCustomSSL": { - "value": "[parameters('enableCustomSSL')]" - }, - "keyVaultCustomTrustKeyStorePassPhrase": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStorePassPhraseSecretName'), reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.customTrustKeyStorePassPhraseSecretName.value)]" - } - }, - "keyVaultCustomTrustKeyStoreType": { - "value": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStoreType'), parameters('uploadedCustomTrustKeyStoreType'))]" - } - } - } - }, - { - "name": "elkLinkedTemplate", - "type": "Microsoft.Resources/deployments", - "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'aadLinkedTemplate')]", - "[resourceId('Microsoft.Resources/deployments', 'aadLinkedTemplateWithCustomSSL')]" - ], - "apiVersion": "${azure.apiVersion}", - "condition": "[parameters('enableELK')]", - "properties": { - "mode": "Incremental", - "templateLink": { - "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_elkLinkedTemplateName')))]", - "contentVersion": "1.0.0.0" - }, - "parameters": { - "_artifactsLocation": { - "value": "[parameters('_artifactsLocation')]" - }, - "_artifactsLocationSasToken": { - "value": "[parameters('_artifactsLocationSasToken')]" - }, - "adminVMName": { - "value": "[parameters('adminVMName')]" - }, - "elasticsearchEndpoint": { - "value": "[parameters('elasticsearchEndpoint')]" - }, - "elasticsearchPassword": { - "value": "[parameters('elasticsearchPassword')]" - }, - "elasticsearchUserName": { - "value": "[parameters('elasticsearchUserName')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "logsToIntegrate": { - "value": "[parameters('logsToIntegrate')]" - }, - "managedServerPrefix": { - "value": "[parameters('managedServerPrefix')]" + "managedVMNamePrefix": { + "value": "[variables('name_managedVMNamePrefix')]" }, "numberOfManagedApplicationInstances": { "value": "[add(parameters('numberOfInstances'),-1)]" }, + "tagsByResource": { + "value": "[variables('obj_tagsByResources')]" + }, "wlsDomainName": { "value": "[parameters('wlsDomainName')]" }, @@ -1410,10 +1178,11 @@ { "name": "coherenceTemplate", "type": "Microsoft.Resources/deployments", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'elkLinkedTemplate')]" + "[resourceId('Microsoft.Resources/deployments', 'dbLinkedTemplate')]" ], - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "condition": "[and(parameters('enableCoherence'),not(parameters('enableCustomSSL')))]", "properties": { "mode": "Incremental", @@ -1428,6 +1197,9 @@ "_artifactsLocationSasToken": { "value": "[parameters('_artifactsLocationSasToken')]" }, + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" + }, "adminPasswordOrKey": { "value": "[parameters('adminPasswordOrKey')]" }, @@ -1435,7 +1207,10 @@ "value": "[parameters('adminUsername')]" }, "adminVMName": { - "value": "[parameters('adminVMName')]" + "value": "[variables('name_adminVM')]" + }, + "adminVMNamePrefix": { + "value": "[parameters('adminVMNamePrefix')]" }, "authenticationType": { "value": "[parameters('authenticationType')]" @@ -1443,33 +1218,18 @@ "dnsLabelPrefix": { "value": "[parameters('dnsLabelPrefix')]" }, - "elasticsearchEndpoint": { - "value": "[parameters('elasticsearchEndpoint')]" - }, - "elasticsearchPassword": { - "value": "[parameters('elasticsearchPassword')]" - }, - "elasticsearchUserName": { - "value": "[parameters('elasticsearchUserName')]" - }, "enableCoherenceWebLocalStorage": { "value": "[parameters('enableCoherenceWebLocalStorage')]" }, - "enableELK": { - "value": "[parameters('enableELK')]" - }, "location": { "value": "[parameters('location')]" }, - "logIndex": { - "value": "[if(parameters('enableELK'), reference('elkLinkedTemplate', '${azure.apiVersion}').outputs.logIndex.value, '')]" - }, - "logsToIntegrate": { - "value": "[parameters('logsToIntegrate')]" - }, "managedServerPrefix": { "value": "[parameters('managedServerPrefix')]" }, + "managedVMNamePrefix": { + "value": "[variables('name_managedVMNamePrefix')]" + }, "numberOfCoherenceCacheInstances": { "value": "[parameters('numberOfCoherenceCacheInstances')]" }, @@ -1477,13 +1237,25 @@ "value": "[parameters('skuUrnVersion')]" }, "storageAccountName": { - "value": "[reference(variables('clusterTemplateRef'), '${azure.apiVersion}').outputs.storageAccountName.value]" + "value": "[reference(variables('clusterTemplateRef'), '${azure.apiVersionForDeployment}').outputs.storageAccountName.value]" + }, + "subnetName": { + "value": "[parameters('subnetName')]" + }, + "tagsByResource": { + "value": "[variables('obj_tagsByResources')]" }, "usePreviewImage": { "value": "[parameters('usePreviewImage')]" }, "vmSizeSelectForCoherence": { - "value": "[parameters('vmSizeSelectForCoherence')]" + "value": "[variables('const_vmSizeCoherence')]" + }, + "virtualNetworkResourceGroupName": { + "value": "[parameters('virtualNetworkResourceGroupName')]" + }, + "virtualNetworkName": { + "value": "[parameters('virtualNetworkName')]" }, "wlsDomainName": { "value": "[parameters('wlsDomainName')]" @@ -1494,6 +1266,12 @@ "wlsUserName": { "value": "[parameters('wlsUserName')]" }, + "enableDNSConfiguration": { + "value": "[parameters('enableDNSConfiguration')]" + }, + "customDNSNameForAdminServer": { + "value": "[if(parameters('enableDNSConfiguration'), format('{0}.{1}', parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')),'')]" + }, "enableCustomSSL": { "value": "[parameters('enableCustomSSL')]" } @@ -1503,10 +1281,11 @@ { "name": "coherenceTemplateWithCustomSSL", "type": "Microsoft.Resources/deployments", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'elkLinkedTemplate')]" + "[resourceId('Microsoft.Resources/deployments', 'dbLinkedTemplate')]" ], - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "condition": "[and(parameters('enableCoherence'),parameters('enableCustomSSL'))]", "properties": { "mode": "Incremental", @@ -1521,6 +1300,9 @@ "_artifactsLocationSasToken": { "value": "[parameters('_artifactsLocationSasToken')]" }, + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" + }, "adminPasswordOrKey": { "value": "[parameters('adminPasswordOrKey')]" }, @@ -1528,41 +1310,29 @@ "value": "[parameters('adminUsername')]" }, "adminVMName": { - "value": "[parameters('adminVMName')]" + "value": "[variables('name_adminVM')]" }, + "adminVMNamePrefix": { + "value": "[parameters('adminVMNamePrefix')]" + }, "authenticationType": { "value": "[parameters('authenticationType')]" }, "dnsLabelPrefix": { "value": "[parameters('dnsLabelPrefix')]" }, - "elasticsearchEndpoint": { - "value": "[parameters('elasticsearchEndpoint')]" - }, - "elasticsearchPassword": { - "value": "[parameters('elasticsearchPassword')]" - }, - "elasticsearchUserName": { - "value": "[parameters('elasticsearchUserName')]" - }, "enableCoherenceWebLocalStorage": { "value": "[parameters('enableCoherenceWebLocalStorage')]" }, - "enableELK": { - "value": "[parameters('enableELK')]" - }, "location": { "value": "[parameters('location')]" }, - "logIndex": { - "value": "[if(parameters('enableELK'), reference('elkLinkedTemplate', '${azure.apiVersion}').outputs.logIndex.value, '')]" - }, - "logsToIntegrate": { - "value": "[parameters('logsToIntegrate')]" - }, "managedServerPrefix": { "value": "[parameters('managedServerPrefix')]" }, + "managedVMNamePrefix": { + "value": "[variables('name_managedVMNamePrefix')]" + }, "numberOfCoherenceCacheInstances": { "value": "[parameters('numberOfCoherenceCacheInstances')]" }, @@ -1570,13 +1340,25 @@ "value": "[parameters('skuUrnVersion')]" }, "storageAccountName": { - "value": "[reference(variables('clusterTemplateRef'), '${azure.apiVersion}').outputs.storageAccountName.value]" + "value": "[reference(variables('clusterTemplateRef'), '${azure.apiVersionForDeployment}').outputs.storageAccountName.value]" + }, + "subnetName": { + "value": "[parameters('subnetName')]" + }, + "tagsByResource": { + "value": "[variables('obj_tagsByResources')]" }, "usePreviewImage": { "value": "[parameters('usePreviewImage')]" }, "vmSizeSelectForCoherence": { - "value": "[parameters('vmSizeSelectForCoherence')]" + "value": "[variables('const_vmSizeCoherence')]" + }, + "virtualNetworkResourceGroupName": { + "value": "[parameters('virtualNetworkResourceGroupName')]" + }, + "virtualNetworkName": { + "value": "[parameters('virtualNetworkName')]" }, "wlsDomainName": { "value": "[parameters('wlsDomainName')]" @@ -1587,122 +1369,188 @@ "wlsUserName": { "value": "[parameters('wlsUserName')]" }, + "enableDNSConfiguration": { + "value": "[parameters('enableDNSConfiguration')]" + }, + "customDNSNameForAdminServer": { + "value": "[if(parameters('enableDNSConfiguration'), format('{0}.{1}', parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')),'')]" + }, "enableCustomSSL": { "value": "[parameters('enableCustomSSL')]" }, - "keyVaultCustomIdentityKeyStoreData": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomIdentityKeyStoreDataSecretName'),reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.customIdentityKeyStoreDataSecretName.value)]" - } + "sslCustomIdentityKeyStoreData": { + "value": "[parameters('uploadedCustomIdentityKeyStoreData')]" }, - "keyVaultCustomIdentityKeyStorePassPhrase": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomIdentityKeyStorePassPhraseSecretName'), reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.customIdentityKeyStorePassPhraseSecretName.value)]" - } + "sslCustomIdentityKeyStorePassPhrase": { + "value": "[parameters('uploadedCustomIdentityKeyStorePassphrase')]" }, - "keyVaultCustomIdentityKeyStoreType":{ - "value": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomIdentityKeyStoreType'), parameters('uploadedCustomIdentityKeyStoreType'))]" + "sslCustomIdentityKeyStoreType": { + "value": "[parameters('uploadedCustomIdentityKeyStoreType')]" }, - "keyVaultCustomTrustKeyStoreData": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStoreDataSecretName'), reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.customTrustKeyStoretDataSecretName.value)]" - } - }, - "keyVaultCustomTrustKeyStorePassPhrase": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStorePassPhraseSecretName'), reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.customTrustKeyStorePassPhraseSecretName.value)]" - } - }, - "keyVaultCustomTrustKeyStoreType":{ - "value": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStoreType'), parameters('uploadedCustomTrustKeyStoreType'))]" - }, - "keyVaultPrivateKeyAlias":{ - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultPrivateKeyAliasSecretName'), reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.privateKeyAliasSecretName.value)]" - } - }, - "keyVaultPrivateKeyPassPhrase": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultPrivateKeyPassPhraseSecretName'), reference('sslKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.privateKeyPassPhraseSecretName.value)]" - } + "sslCustomTrustKeyStoreData": { + "value": "[parameters('uploadedCustomTrustKeyStoreData')]" + }, + "sslCustomTrustKeyStorePassPhrase": { + "value": "[parameters('uploadedCustomTrustKeyStorePassPhrase')]" + }, + "sslCustomTrustKeyStoreType": { + "value": "[parameters('uploadedCustomTrustKeyStoreType')]" + }, + "sslPrivateKeyAlias": { + "value": "[parameters('uploadedPrivateKeyAlias')]" + }, + "sslPrivateKeyPassPhrase": { + "value": "[parameters('uploadedPrivateKeyPassPhrase')]" } } } }, { - "apiVersion": "${azure.apiVersion}", - "name": "${cluster.end}", "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "[variables('name_uamiForPostDeploymentScript')]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'existing')]", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", "dependsOn": [ "[resourceId('Microsoft.Resources/deployments', variables('clusterTemplateRef'))]", - "[resourceId('Microsoft.Resources/deployments', 'keyVaultLinkedTemplate')]", - "[resourceId('Microsoft.Resources/deployments', 'keyVaultLinkedAppGatewayTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'keyVaultwithSelfSignedAppGatewaySSLCert')]", + "[resourceId('Microsoft.Resources/deployments', 'appGatewayLinkedTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'dnszonesLinkedTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'dbLinkedTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'coherenceTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'coherenceTemplateWithCustomSSL')]" + ], + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_postDeploymentUAMIRolesTemplate')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" + }, + "tagsByResource": { + "value": "[variables('obj_tagsByResources')]" + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "postDeplyment", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'existing')]", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', variables('clusterTemplateRef'))]", + "[resourceId('Microsoft.Resources/deployments', 'keyVaultwithSelfSignedAppGatewaySSLCert')]", + "[resourceId('Microsoft.Resources/deployments', 'appGatewayLinkedTemplate')]", "[resourceId('Microsoft.Resources/deployments', 'dnszonesLinkedTemplate')]", "[resourceId('Microsoft.Resources/deployments', 'dbLinkedTemplate')]", - "[resourceId('Microsoft.Resources/deployments', 'aadLinkedTemplate')]", - "[resourceId('Microsoft.Resources/deployments', 'aadLinkedTemplateWithCustomSSL')]", - "[resourceId('Microsoft.Resources/deployments', 'elkLinkedTemplate')]", "[resourceId('Microsoft.Resources/deployments', 'coherenceTemplate')]", "[resourceId('Microsoft.Resources/deployments', 'coherenceTemplateWithCustomSSL')]", - "[resourceId('Microsoft.Resources/deployments', 'sslKeyVaultNestedTemplate')]" + "[resourceId('Microsoft.Resources/deployments', variables('name_uamiForPostDeploymentScript'))]" + + ], + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_postDeploymentTemplate')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" + }, + "tagsByResource": { + "value": "[variables('obj_tagsByResources')]" + }, + "const_guidTag":{ + "value": "[variables('const_guidTag')]" + }, + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + }, + "userAssignedIdentityResourceId":{ + "value": "[reference(variables('name_uamiForPostDeploymentScript'),'${azure.apiVersionForDeployment}').outputs.uamidForPostDeployment.value]" + } + } + } + }, + { + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${cluster.end}", + "type": "Microsoft.Resources/deployments", + "tags": "[variables('obj_tagsByResources')['${identifier.resourcesDeployment}']]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', variables('clusterTemplateRef'))]", + "[resourceId('Microsoft.Resources/deployments', 'keyVaultwithSelfSignedAppGatewaySSLCert')]", + "[resourceId('Microsoft.Resources/deployments', 'appGatewayLinkedTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'dnszonesLinkedTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'dbLinkedTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'coherenceTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'coherenceTemplateWithCustomSSL')]" ], "properties": { "mode": "Incremental", "template": { "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", - "resources": [ - ] + "resources": [] } } } ], "outputs": { + "adminVMName": { + "type": "string", + "value": "[variables('name_adminVM')]" + }, + "managedServerVMNamePrefix": { + "type": "string", + "value": "[concat(parameters('managedServerPrefix'), variables('const_globalResourceNameSuffix'), 'VM')]" + }, "wlsDomainLocation": { "type": "string", - "value": "[reference(variables('clusterTemplateRef'), '${azure.apiVersion}').outputs.wlsDomainLocation.value]" + "value": "[reference(variables('clusterTemplateRef'), '${azure.apiVersionForDeployment}').outputs.wlsDomainLocation.value]" }, "adminHostName": { "type": "string", - "value": "[reference(variables('clusterTemplateRef'), '${azure.apiVersion}').outputs.adminHostName.value]" + "value": "[reference(variables('clusterTemplateRef'), '${azure.apiVersionForDeployment}').outputs.adminHostName.value]" }, "adminConsole": { "type": "string", - "value": "[if(parameters('enableDNSConfiguration'), format('http://{0}.{1}:7001/console', parameters('dnszoneAdminConsoleLabel'), parameters('dnszoneName')),reference(variables('clusterTemplateRef'), '${azure.apiVersion}').outputs.adminConsole.value)]" + "value": "[if(parameters('enableDNSConfiguration'), uri(format('http://{0}.{1}:7001/console/', parameters('dnszoneAdminConsoleLabel'), parameters('dnszoneName')), ''),reference(variables('clusterTemplateRef'), '${azure.apiVersionForDeployment}').outputs.adminConsole.value)]" }, "adminSecuredConsole": { "type": "string", - "value": "[if(parameters('enableDNSConfiguration'), format('https://{0}.{1}:7002/console', parameters('dnszoneAdminConsoleLabel'), parameters('dnszoneName')),reference(variables('clusterTemplateRef'), '${azure.apiVersion}').outputs.adminSecuredConsole.value)]" + "value": "[if(parameters('enableDNSConfiguration'), uri(format('https://{0}.{1}:7002/console/', parameters('dnszoneAdminConsoleLabel'), parameters('dnszoneName')), ''),reference(variables('clusterTemplateRef'), '${azure.apiVersionForDeployment}').outputs.adminSecuredConsole.value)]" }, - "appGatewayURL": { + "adminRemoteConsoleURL": { "type": "string", - "value": "[if(parameters('enableAppGateway'), if(parameters('enableDNSConfiguration'), format('http://{0}.{1}', parameters('dnszoneAppGatewayLabel'),parameters('dnszoneName')), reference('keyVaultLinkedAppGatewayTemplate', '${azure.apiVersion}').outputs.appGatewayURL.value),'')]" + "value": "[if(parameters('enableDNSConfiguration'), uri(format('http://{0}.{1}:7001', parameters('dnszoneAdminConsoleLabel'), parameters('dnszoneName')), ''),reference(variables('clusterTemplateRef'), '${azure.apiVersionForDeployment}').outputs.adminRemoteConsoleURL.value)]" }, - "appGatewaySecuredURL": { + "adminRemoteConsoleSecuredURL": { "type": "string", - "value": "[if(parameters('enableAppGateway'), if(parameters('enableDNSConfiguration'), format('https://{0}.{1}', parameters('dnszoneAppGatewayLabel'),parameters('dnszoneName')), reference('keyVaultLinkedAppGatewayTemplate', '${azure.apiVersion}').outputs.appGatewaySecuredURL.value),'')]" + "value": "[if(parameters('enableDNSConfiguration'), uri(format('https://{0}.{1}:7002', parameters('dnszoneAdminConsoleLabel'), parameters('dnszoneName')), ''),reference(variables('clusterTemplateRef'), '${azure.apiVersionForDeployment}').outputs.adminRemoteConsoleSecuredURL.value)]" }, - "logIndex": { + "appGatewayURL": { + "type": "string", + "value": "[if(parameters('enableAppGateway'), if(parameters('enableDNSConfiguration'), uri(concat('http://',parameters('dnszoneAppGatewayLabel'),'.',parameters('dnszoneName')),''), reference('appGatewayLinkedTemplate', '${azure.apiVersionForDeployment}').outputs.appGatewayURL.value),'')]" + }, + "appGatewaySecuredURL": { "type": "string", - "value": "[if(parameters('enableELK'), reference('elkLinkedTemplate', '${azure.apiVersion}').outputs.logIndex.value, '')]" + "value": "[if(parameters('enableAppGateway'), if(parameters('enableDNSConfiguration'), uri(concat('https://',parameters('dnszoneAppGatewayLabel'),'.',parameters('dnszoneName')),''), reference('appGatewayLinkedTemplate', '${azure.apiVersionForDeployment}').outputs.appGatewaySecuredURL.value),'')]" } } } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_keyvaultAppGatewayConnectorTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_appGatewayConnectorTemplate.json similarity index 59% rename from weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_keyvaultAppGatewayConnectorTemplate.json rename to weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_appGatewayConnectorTemplate.json index 7d1ab6331..8b4415932 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_keyvaultAppGatewayConnectorTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_appGatewayConnectorTemplate.json @@ -16,12 +16,17 @@ } }, "adminVMName": { - "defaultValue": "adminVM", "type": "string", "metadata": { "description": "Admin Server hosting VM name." } }, + "appGatewayName": { + "type": "string", + "metadata": { + "description": "Name of the Application Gateway" + } + }, "appGatewayCertificateOption": { "defaultValue": "haveCert", "type": "string", @@ -29,11 +34,31 @@ "description": "Three scenarios we support for deploying app gateway" }, "allowedValues": [ - "haveKeyVault", "haveCert", "generateCert" ] }, + "appGatewaySSLBackendCertData": { + "defaultValue": "", + "type": "securestring", + "metadata": { + "description": "The one-line, base64 string of the SSL backend certificate data." + } + }, + "autoGeneratedSSLCertKeyVaultName": { + "defaultValue": "[newGuid()]", + "type": "string", + "metadata": { + "description": "Name of Key Vault that stores auto-generated self-signed certificate." + } + }, + "autoGeneratedSSLCertSecretName": { + "defaultValue": "[newGuid()]", + "type": "string", + "metadata": { + "description": "Name of Key Vault Secret that stores auto-generated self-signed certificate." + } + }, "customDomainNameforApplicationGateway": { "defaultValue": "application.contoso.xyz", "type": "string", @@ -48,6 +73,17 @@ "description": "Azure DNS for Application Gateway" } }, + "enableCustomSSL": { + "defaultValue": false, + "type": "bool" + }, + "enableCookieBasedAffinity": { + "defaultValue": true, + "type": "bool", + "metadata": { + "description": "true to enable cookie based affinity." + } + }, "gatewayPublicIPAddressName": { "defaultValue": "gwip", "type": "string", @@ -55,82 +91,85 @@ "description": "Public IP Name for the Application Gateway" } }, - "keyVaultName": { - "defaultValue": "", + "location": { "type": "string", "metadata": { - "description": "Key Vault name" + "description": "Location for all resources." } }, - "keyVaultNamefromDeploymentOutput": { - "defaultValue": "", + "managedVMNamePrefix": { "type": "string", "metadata": { - "description": "Key Vault name that output from Key Vault linked template deployment." + "description": "Provide managed VM prefix names" } }, - "keyVaultResourceGroup": { - "defaultValue": "", - "type": "string", + "numberOfInstances": { + "defaultValue": 2, + "type": "int", + "minValue": 2, + "maxValue": 5, "metadata": { - "description": "Name of resource group in current subscription containing the Key Vault" + "description": "Number of VMs to deploy, limit 5 since this sample is using a single storage account" } }, - "keyVaultSSLCertDataSecretName": { - "defaultValue": "myCertSecretData", - "type": "string", + "overrideHostName": { + "defaultValue": false, + "type": "bool", "metadata": { - "description": "The name of the secret in the specified Key Vault whose value is the SSL Certificate Data," + "description": "If true, will override the host name with dnszoneSubDomain." } }, - "keyVaultSSLCertDataSecretNamefromDeploymentOutput": { - "defaultValue": "", - "type": "string", + "sslCertData": { + "defaultValue": "[newGuid()]", + "type": "securestring", "metadata": { - "description": "The name of the secret in the specified Key Vault whose value is the SSL Certificate Data, that output from Key Vault linked template deployment." + "description": "Uploaded certificate base64 string." } }, - "keyVaultSSLCertPasswordSecretName": { - "defaultValue": "", - "type": "string", + "sslCertPswData": { + "defaultValue": "[newGuid()]", + "type": "securestring", "metadata": { - "description": "The name of the secret in the specified Key Vault whose value is the password for the SSL Certificate" + "description": "The password of uploaded certificate." } }, - "keyVaultSSLCertPasswordSecretNamefromDeploymentOutput": { - "defaultValue": "", - "type": "string", + "tagsByResource": { + "type": "object", + "defaultValue": {}, "metadata": { - "description": "The name of the secret in the specified Key Vault whose value is the password for the SSL Certificate, that output from Key Vault linked template deployment." + "description": "${label.tagsLabel}" } }, - "location": { + "virtualNetworkNewOrExisting": { "type": "string", + "defaultValue": "new", + "allowedValues": [ + "new", + "existing" + ], "metadata": { - "description": "Location for all resources." + "description": "Specify whether to create a new or existing virtual network for the VM." } }, - "managedServerPrefix": { - "defaultValue": "msp", + "virtualNetworkName": { "type": "string", + "defaultValue": "wls-vnet", "metadata": { - "description": "Provide managed server prefix names" + "description": "Name of the existing or new VNET" } }, - "numberOfInstances": { - "defaultValue": 2, - "type": "int", - "minValue": 2, - "maxValue": 5, + "virtualNetworkResourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", "metadata": { - "description": "Number of VMs to deploy, limit 5 since this sample is using a single storage account" + "description": "Resource group of Virtual network" } }, - "overrideHostName": { - "defaultValue": false, - "type": "bool", + "subnetForAppGateway": { + "type": "string", + "defaultValue": "appgateway-subnet", "metadata": { - "description": "If true, will override the host name with dnszoneSubDomain." + "description": "Name of the existing or new Subnet for Application Gateway" } }, "wlsDomainName": { @@ -157,84 +196,29 @@ "variables": { "const_appGatewaySSLCertOptionGenerateCert": "generateCert", "const_appGatewaySSLCertOptionHaveCert": "haveCert", - "const_appGatewaySSLCertOptionHaveKeyVault": "haveKeyVault", - "const_currentSubscription": "[subscription().subscriptionId]", "name_appGatewayLinkedTemplate": "appGatewayNestedTemplate.json" }, "resources": [ { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "appGatewaywithExistingKeyVaultTemplate", - "condition": "[equals(parameters('appGatewayCertificateOption'), variables('const_appGatewaySSLCertOptionHaveKeyVault'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${cluster.appgateway.custom.certificate}", + "condition": "[not(equals(parameters('appGatewayCertificateOption'), variables('const_appGatewaySSLCertOptionGenerateCert')))]", "properties": { "mode": "Incremental", - "templateLink": { - "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_appGatewayLinkedTemplate')))]", - "contentVersion": "1.0.0.0" - }, - "parameters": { - "_artifactsLocation": { - "value": "[parameters('_artifactsLocation')]" - }, - "_artifactsLocationSasToken": { - "value": "[parameters('_artifactsLocationSasToken')]" - }, - "adminVMName": { - "value": "[parameters('adminVMName')]" - }, - "appGatewaySSLCertificateData": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), parameters('keyVaultResourceGroup'), 'Microsoft.KeyVault/vaults', parameters('keyVaultName'))]" - }, - "secretName": "[parameters('keyVaultSSLCertDataSecretName')]" - } - }, - "appGatewaySSLCertificatePassword": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), parameters('keyVaultResourceGroup'), 'Microsoft.KeyVault/vaults', parameters('keyVaultName'))]" - }, - "secretName": "[parameters('keyVaultSSLCertPasswordSecretName')]" - } - }, - "customDomainName": { - "value": "[parameters('customDomainNameforApplicationGateway')]" - }, - "dnsNameforApplicationGateway": { - "value": "[parameters('domainLabelforApplicationGateway')]" - }, - "gatewayPublicIPAddressName": { - "value": "[parameters('gatewayPublicIPAddressName')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "managedServerPrefix": { - "value": "[parameters('managedServerPrefix')]" - }, - "numberOfInstances": { - "value": "[parameters('numberOfInstances')]" - }, - "overrideHostName": { - "value": "[parameters('overrideHostName')]" - }, - "wlsDomainName": { - "value": "[parameters('wlsDomainName')]" - }, - "wlsPassword": { - "value": "[parameters('wlsPassword')]" - }, - "wlsUserName": { - "value": "[parameters('wlsUserName')]" - } + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] } } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "name": "appGatewaywithExistingSSLCertTemplate", "condition": "[equals(parameters('appGatewayCertificateOption'), variables('const_appGatewaySSLCertOptionHaveCert'))]", "properties": { @@ -253,21 +237,17 @@ "adminVMName": { "value": "[parameters('adminVMName')]" }, + "appGatewayName": { + "value": "[parameters('appGatewayName')]" + }, + "appGatewaySSLBackendCertData": { + "value": "[parameters('appGatewaySSLBackendCertData')]" + }, "appGatewaySSLCertificateData": { - "reference": { - "keyVault": { - "id": "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultNamefromDeploymentOutput'))]" - }, - "secretName": "[parameters('keyVaultSSLCertDataSecretNamefromDeploymentOutput')]" - } + "value": "[parameters('sslCertData')]" }, "appGatewaySSLCertificatePassword": { - "reference": { - "keyVault": { - "id": "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultNamefromDeploymentOutput'))]" - }, - "secretName": "[parameters('keyVaultSSLCertPasswordSecretNamefromDeploymentOutput')]" - } + "value": "[parameters('sslCertPswData')]" }, "customDomainName": { "value": "[parameters('customDomainNameforApplicationGateway')]" @@ -275,14 +255,20 @@ "dnsNameforApplicationGateway": { "value": "[parameters('domainLabelforApplicationGateway')]" }, + "enableCustomSSL": { + "value": "[parameters('enableCustomSSL')]" + }, + "enableCookieBasedAffinity": { + "value": "[parameters('enableCookieBasedAffinity')]" + }, "gatewayPublicIPAddressName": { "value": "[parameters('gatewayPublicIPAddressName')]" }, "location": { "value": "[parameters('location')]" }, - "managedServerPrefix": { - "value": "[parameters('managedServerPrefix')]" + "managedVMNamePrefix": { + "value": "[parameters('managedVMNamePrefix')]" }, "numberOfInstances": { "value": "[parameters('numberOfInstances')]" @@ -290,6 +276,21 @@ "overrideHostName": { "value": "[parameters('overrideHostName')]" }, + "tagsByResource": { + "value": "[parameters('tagsByResource')]" + }, + "virtualNetworkNewOrExisting": { + "value": "[parameters('virtualNetworkNewOrExisting')]" + }, + "virtualNetworkName": { + "value": "[parameters('virtualNetworkName')]" + }, + "virtualNetworkResourceGroupName": { + "value": "[parameters('virtualNetworkResourceGroupName')]" + }, + "subnetForAppGateway": { + "value": "[parameters('subnetForAppGateway')]" + }, "wlsDomainName": { "value": "[parameters('wlsDomainName')]" }, @@ -304,7 +305,8 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "name": "appGatewaywithSelfSignedSSLCertTemplate", "condition": "[equals(parameters('appGatewayCertificateOption'), variables('const_appGatewaySSLCertOptionGenerateCert'))]", "properties": { @@ -323,12 +325,18 @@ "adminVMName": { "value": "[parameters('adminVMName')]" }, + "appGatewayName": { + "value": "[parameters('appGatewayName')]" + }, + "appGatewaySSLBackendCertData": { + "value": "[parameters('appGatewaySSLBackendCertData')]" + }, "appGatewaySSLCertificateData": { "reference": { "keyVault": { - "id": "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultNamefromDeploymentOutput'))]" + "id": "[resourceId('Microsoft.KeyVault/vaults', parameters('autoGeneratedSSLCertKeyVaultName'))]" }, - "secretName": "[parameters('keyVaultSSLCertDataSecretNamefromDeploymentOutput')]" + "secretName": "[parameters('autoGeneratedSSLCertSecretName')]" } }, "appGatewaySSLCertificatePassword": { @@ -340,14 +348,20 @@ "dnsNameforApplicationGateway": { "value": "[parameters('domainLabelforApplicationGateway')]" }, + "enableCustomSSL": { + "value": "[parameters('enableCustomSSL')]" + }, + "enableCookieBasedAffinity": { + "value": "[parameters('enableCookieBasedAffinity')]" + }, "gatewayPublicIPAddressName": { "value": "[parameters('gatewayPublicIPAddressName')]" }, "location": { "value": "[parameters('location')]" }, - "managedServerPrefix": { - "value": "[parameters('managedServerPrefix')]" + "managedVMNamePrefix": { + "value": "[parameters('managedVMNamePrefix')]" }, "numberOfInstances": { "value": "[parameters('numberOfInstances')]" @@ -355,6 +369,21 @@ "overrideHostName": { "value": "[parameters('overrideHostName')]" }, + "tagsByResource": { + "value": "[parameters('tagsByResource')]" + }, + "virtualNetworkNewOrExisting": { + "value": "[parameters('virtualNetworkNewOrExisting')]" + }, + "virtualNetworkName": { + "value": "[parameters('virtualNetworkName')]" + }, + "virtualNetworkResourceGroupName": { + "value": "[parameters('virtualNetworkResourceGroupName')]" + }, + "subnetForAppGateway": { + "value": "[parameters('subnetForAppGateway')]" + }, "wlsDomainName": { "value": "[parameters('wlsDomainName')]" }, @@ -371,19 +400,17 @@ "outputs": { "appGatewayAlias": { "type": "string", - "value": "[if(equals(parameters('appGatewayCertificateOption'), variables('const_appGatewaySSLCertOptionHaveKeyVault')), - reference('appGatewaywithExistingKeyVaultTemplate', '${azure.apiVersion}').outputs.appGatewayAlias.value, - if(equals(parameters('appGatewayCertificateOption'),variables('const_appGatewaySSLCertOptionHaveCert')), - reference('appGatewaywithExistingSSLCertTemplate', '${azure.apiVersion}').outputs.appGatewayAlias.value, - reference('appGatewaywithSelfSignedSSLCertTemplate', '${azure.apiVersion}').outputs.appGatewayAlias.value))]" + "value": "[if(equals(parameters('appGatewayCertificateOption'),variables('const_appGatewaySSLCertOptionHaveCert')), + reference('appGatewaywithExistingSSLCertTemplate', '${azure.apiVersionForDeployment}').outputs.appGatewayAlias.value, + reference('appGatewaywithSelfSignedSSLCertTemplate', '${azure.apiVersionForDeployment}').outputs.appGatewayAlias.value)]" }, "appGatewayURL": { "type": "string", - "value": "[if(equals(parameters('appGatewayCertificateOption'), variables('const_appGatewaySSLCertOptionHaveKeyVault')),reference('appGatewaywithExistingKeyVaultTemplate', '${azure.apiVersion}').outputs.appGatewayURL.value, if(equals(parameters('appGatewayCertificateOption'),variables('const_appGatewaySSLCertOptionHaveCert')),reference('appGatewaywithExistingSSLCertTemplate', '${azure.apiVersion}').outputs.appGatewayURL.value, reference('appGatewaywithSelfSignedSSLCertTemplate', '${azure.apiVersion}').outputs.appGatewayURL.value))]" + "value": "[if(equals(parameters('appGatewayCertificateOption'),variables('const_appGatewaySSLCertOptionHaveCert')),reference('appGatewaywithExistingSSLCertTemplate', '${azure.apiVersionForDeployment}').outputs.appGatewayURL.value, reference('appGatewaywithSelfSignedSSLCertTemplate', '${azure.apiVersionForDeployment}').outputs.appGatewayURL.value)]" }, "appGatewaySecuredURL": { "type": "string", - "value": "[if(equals(parameters('appGatewayCertificateOption'), variables('const_appGatewaySSLCertOptionHaveKeyVault')),reference('appGatewaywithExistingKeyVaultTemplate', '${azure.apiVersion}').outputs.appGatewaySecuredURL.value, if(equals(parameters('appGatewayCertificateOption'),variables('const_appGatewaySSLCertOptionHaveCert')),reference('appGatewaywithExistingSSLCertTemplate', '${azure.apiVersion}').outputs.appGatewaySecuredURL.value, reference('appGatewaywithSelfSignedSSLCertTemplate', '${azure.apiVersion}').outputs.appGatewaySecuredURL.value))]" + "value": "[if(equals(parameters('appGatewayCertificateOption'),variables('const_appGatewaySSLCertOptionHaveCert')),reference('appGatewaywithExistingSSLCertTemplate', '${azure.apiVersionForDeployment}').outputs.appGatewaySecuredURL.value, reference('appGatewaywithSelfSignedSSLCertTemplate', '${azure.apiVersionForDeployment}').outputs.appGatewaySecuredURL.value)]" } } } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_appendUserManagedIdentity.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_appendUserManagedIdentity.json new file mode 100644 index 000000000..ba47748a4 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_appendUserManagedIdentity.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "vmName": { + "type": "string" + }, + "existingIdentities": { + "type": "object" + }, + "newIdentities": { + "type": "object" + }, + "location": { + "type": "string" + } + }, + "resources": [ + { + "apiVersion": "${azure.apiVersionForVirtualMachines}", + "type": "Microsoft.Compute/virtualMachines", + "name": "[parameters('vmName')]", + "location": "[parameters('location')]", + "identity": { + "type": "userAssigned", + "userAssignedIdentities": "[union(parameters('existingIdentities'),parameters('newIdentities'))]" + } + } + ] +} \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_dbTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_dbTemplate.json new file mode 100644 index 000000000..4daf450f0 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_dbTemplate.json @@ -0,0 +1,258 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." + } + }, + "_artifactsLocationDbTemplate": { + "defaultValue": "[if(contains(parameters('_artifactsLocation'), 'githubusercontent'), parameters('_artifactsLocation'), deployment().properties.templateLink.uri)]", + "type": "string", + "metadata": { + "description": "If we are deploying from the command line, use the passed in _artifactsLocation, otherwise use the default." + } + }, + "_artifactsLocationSasToken": { + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." + }, + "defaultValue": "" + }, + "adminVMName": { + "defaultValue": "adminVM", + "type": "string", + "metadata": { + "description": "Admin Server hosting VM name." + } + }, + "databaseType": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "One of the supported database types" + } + }, + "dbGlobalTranPro": { + "defaultValue": "OnePhaseCommit", + "type": "string", + "metadata": { + "description": "Determines the transaction protocol (global transaction processing behavior) for the data source." + } + }, + "dsConnectionURL": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "JDBC Connection String" + } + }, + "dbUser": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Userid of Database" + } + }, + "dbPassword": { + "defaultValue": "[newGuid()]", + "type": "securestring", + "metadata": { + "description": "Password for Database" + } + }, + "enablePswlessConnection": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "True to enable passwordless connection." + } + }, + "jdbcDataSourceName": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "JNDI Name for JDBC Datasource" + } + }, + "location": { + "type": "string", + "metadata": { + "description": "Location for all resources." + } + }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, + "wlsUserName": { + "defaultValue": "weblogic", + "type": "string", + "metadata": { + "description": "Username for your Weblogic domain name" + } + }, + "wlsPassword": { + "type": "securestring", + "metadata": { + "description": "Password for your Weblogic domain name" + } + } + }, + "variables": { + "const_wlsAdminPort": "7005", + "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", + "name_scriptFilePrefix": "datasourceConfig-", + "name_scriptFileSuffix-sqlserver": "sqlserver.sh", + "name_scriptFileSuffix-oracle": "oracle.sh", + "name_scriptFileSuffix-postgresql": "postgresql.sh", + "name_scriptFileSuffix-mysql": "mysql.sh" + }, + "resources": [ + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${cluster.database.start}", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "apiVersion": "${azure.apiVersionForVirtualMachines}", + "type": "Microsoft.Compute/virtualMachines/extensions", + "tags": "[parameters('tagsByResource')['${identifier.virtualMachinesExtensions}']]", + "name": "[concat(parameters('adminVMName'),'/newuserscript')]", + "location": "[parameters('location')]", + "properties": { + "publisher": "Microsoft.Azure.Extensions", + "type": "CustomScript", + "typeHandlerVersion": "2.0", + "autoUpgradeMinorVersion": true, + "settings": { + "fileUris": [ + "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-sqlserver'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-oracle'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-postgresql'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-mysql'), parameters('_artifactsLocationSasToken')))]" + ] + }, + "protectedSettings": { + "commandToExecute": "[concat('sh',' ',variables('name_scriptFilePrefix'),parameters('databaseType'),'.sh <<< \"',variables('const_wlsHome'),' ',parameters('adminVMName'),' ',variables('const_wlsAdminPort'),' ',parameters('wlsUserName'),' ',base64(parameters('wlsPassword')),' ',base64(parameters('jdbcDataSourceName')),' ',base64(parameters('dsConnectionURL')),' ',parameters('dbUser'),' ',base64(parameters('dbPassword')), ' ',parameters('dbGlobalTranPro'), ' ', parameters('enablePswlessConnection'), '\"')]" + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${cluster.database.end}", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${database.oracle}", + "condition": "[if(contains(parameters('databaseType'), 'oracle'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${database.postgresql}", + "condition": "[if(contains(parameters('databaseType'), 'postgresql'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${database.mysql}", + "condition": "[if(contains(parameters('databaseType'), 'mysql'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${database.sqlserver}", + "condition": "[if(contains(parameters('databaseType'), 'sqlserver'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + } + ], + "outputs": { + "artifactsLocationPassedIn": { + "type": "string", + "value": "[parameters('_artifactsLocation')]" + } + } +} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_dnszones/_createDNSZonesTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_dnszones/_createDNSZonesTemplate.json index 35316550f..2dfcf0629 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_dnszones/_createDNSZonesTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_dnszones/_createDNSZonesTemplate.json @@ -38,6 +38,13 @@ "description": "References to Azure resources from where the DNS resource value is taken. Each item is corresponding to values of dnszonesARecordSetNames." } }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, "ttl": { "type": "int", "defaultValue": 3600, @@ -61,6 +68,7 @@ { "type": "Microsoft.Network/dnszones", "apiVersion": "${azure.apiVersionForDNSZone}", + "tags": "[parameters('tagsByResource')['${identifier.dnszones}']]", "name": "[parameters('dnszoneName')]", "location": "[parameters('location')]", "properties": { diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_dnszones/_uamiAndRoleAssignment.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_dnszones/_uamiAndRoleAssignment.json new file mode 100644 index 000000000..0e2b79f4d --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_dnszones/_uamiAndRoleAssignment.json @@ -0,0 +1,98 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string" + }, + "uamiName": { + "type": "string" + }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + } + }, + "functions": [], + "variables": { + "const_roleDefinitionIdOfContributor": "b24988ac-6180-42a0-ab88-20f7382dd24c", + "name_deploymentScriptContributorRoleAssignmentName": "[guid(format('{0}{1}Deployment Script', resourceGroup().id, parameters('uamiName')))]" + }, + "resources": [ + { + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "${azure.apiVersionForIdentity}", + "tags": "[parameters('tagsByResource')['${identifier.userAssignedIdentities}']]", + "name": "[parameters('uamiName')]", + "location": "[parameters('location')]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "[variables('name_deploymentScriptContributorRoleAssignmentName')]", + "subscriptionId": "[subscription().subscriptionId]", + "location": "[parameters('location')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "roleDefinition": { + "value": "[variables('const_roleDefinitionIdOfContributor')]" + }, + "principalId": { + "value": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('uamiName'))).principalId]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "roleDefinition": { + "type": "string", + "defaultValue": "" + }, + "principalId": { + "type": "string", + "defaultValue": "" + } + }, + "functions": [], + "variables": { + "name_roleAssignmentName": "[guid(format('{0}{1}Role assignment in subscription scope', subscription().id, parameters('principalId')))]" + }, + "resources": [ + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "${azure.apiVersionForRoleAssignment}", + "name": "[variables('name_roleAssignmentName')]", + "properties": { + "description": "Assign subscription scope role to User Assigned Managed Identity ", + "principalId": "[parameters('principalId')]", + "principalType": "ServicePrincipal", + "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinition'))]" + } + } + ], + "outputs": { + "roleId": { + "type": "string", + "value": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinition'))]" + } + } + } + } + } + ], + "outputs": { + "uamiIdForDeploymentScript": { + "type": "string", + "value": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('uamiName'))]" + } + } +} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_dnszones/_updateDNSZonesTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_dnszones/_updateDNSZonesTemplate.json index 74207d21a..c77d29f55 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_dnszones/_updateDNSZonesTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_dnszones/_updateDNSZonesTemplate.json @@ -15,6 +15,12 @@ "description": "If we are deploying from the command line, use the passed in _artifactsLocation, otherwise use the default." } }, + "_globalResourceNameSuffix": { + "type": "string", + "metadata": { + "description": "A unique suffix that was specified during the deployment of the solution template." + } + }, "_artifactsLocationSasToken": { "defaultValue": "", "type": "securestring", @@ -46,12 +52,6 @@ "description": "Azure DNS Zone name." } }, - "identity": { - "type": "Object", - "metadata": { - "description": "Managed identity to be used for the deployment script. Currently, only user-assigned MSI is supported." - } - }, "location": { "type": "string", "metadata": { @@ -70,6 +70,13 @@ "description": "References to Azure resources from where the DNS resource value is taken. Each item is corresponding to values of dnszonesARecordSetNames." } }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, "ttl": { "type": "int", "defaultValue": 3600, @@ -105,25 +112,109 @@ } ], "variables": { - "name_scriptDNSConfiguration": "updateDNSZones.sh" + "name_deploymentScriptUserDefinedManagedIdentity": "wls-vm-dns-user-defined-managed-itentity", + "name_scriptDNSConfiguration": "updateDNSZones.sh", + "name_templateUAMIDeployment": "_uamiAndRoleAssignment.json" }, "resources": [ + { + "type": "Microsoft.Resources/deployments", + "name": "uamiDeployment", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "apiVersion": "${azure.apiVersionForDeployment}", + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/_dnszones/', variables('name_templateUAMIDeployment')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "uamiName": { + "value": "[variables('name_deploymentScriptUserDefinedManagedIdentity')]" + }, + "tagsByResource": { + "value": "[parameters('tagsByResource')]" + } + } + } + }, { "type": "Microsoft.Resources/deploymentScripts", "apiVersion": "${azure.apiVersionForDeploymentScript}", - "name": "script-createDNSRecords", + "tags": "[parameters('tagsByResource')['${identifier.deploymentScripts}']]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'uamiDeployment')]" + ], + "name": "[concat('script-createDNSRecords-', parameters('_globalResourceNameSuffix'))]", "location": "[parameters('location')]", - "identity": "[parameters('identity')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('name_deploymentScriptUserDefinedManagedIdentity'))]": {} + } + }, "kind": "AzureCLI", "properties": { "forceUpdateTag": "[parameters('utcValue')]", - "AzCliVersion": "2.15.0", + "AzCliVersion": "${azure.cli.version}", "timeout": "PT30M", - "arguments": "[format('{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10}', parameters('resourceGroup'), parameters('dnszoneName'), array.join(parameters('dnszonesARecordSetNames')),array.join(parameters('targetResources')), length(parameters('dnszonesARecordSetNames')), length(parameters('targetResources')), parameters('ttl'), array.join(parameters('dnszonesCNAMERecordSetNames')),array.join(parameters('dnszonesCNAMEAlias')),length(parameters('dnszonesCNAMERecordSetNames')), length(parameters('dnszonesCNAMEAlias')))]", + "environmentVariables": [ + { + "name": "DNS_CNAME_ALIAS", + "value": "[array.join(parameters('dnszonesCNAMEAlias'))]" + }, + { + "name": "DNS_CNAME_ALIAS_LENGTH", + "value": "[length(parameters('dnszonesCNAMEAlias'))]" + }, + { + "name": "DNS_CNAME_RECORDSET_LENGTH", + "value": "[length(parameters('dnszonesCNAMERecordSetNames'))]" + }, + { + "name": "DNS_CNAME_RECORDSET_NAMES", + "value": "[array.join(parameters('dnszonesCNAMERecordSetNames'))]" + }, + { + "name": "DNS_RECORDSET_NAMES", + "value": "[array.join(parameters('dnszonesARecordSetNames'))]" + }, + { + "name": "DNS_RECORD_NAMES_LENGTH", + "value": "[length(parameters('dnszonesARecordSetNames'))]" + }, + { + "name": "DNS_TARGET_RESOURCES_LENGTH", + "value": "[length(parameters('targetResources'))]" + }, + { + "name": "DNS_TARGET_RESOURCES", + "value": "[array.join(parameters('targetResources'))]" + }, + { + "name": "DNS_RECORD_TTL", + "value": "[parameters('ttl')]" + }, + { + "name": "DNS_ZONE_NAME", + "value": "[parameters('dnszoneName')]" + }, + { + "name": "MANAGED_IDENTITY_ID", + "value": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('name_deploymentScriptUserDefinedManagedIdentity'))]" + }, + { + "name": "RESOURCE_GROUP_NAME", + "value": "[parameters('resourceGroup')]" + } + ], "primaryScriptUri": "[uri(parameters('_artifactsLocationDNSZonesTemplate'), concat('../../scripts/', variables('name_scriptDNSConfiguration'), parameters('_artifactsLocationSasToken')))]", "cleanupPreference": "OnSuccess", "retentionInterval": "P1D" } } ] -} +} \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_installJdbcLibsTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_installJdbcLibsTemplate.json new file mode 100644 index 000000000..b6d2087d7 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_installJdbcLibsTemplate.json @@ -0,0 +1,135 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." + } + }, + "_artifactsLocationInstallJdbcLibsTemplate": { + "defaultValue": "[if(contains(parameters('_artifactsLocation'), 'githubusercontent'), parameters('_artifactsLocation'), deployment().properties.templateLink.uri)]", + "type": "string", + "metadata": { + "description": "If we are deploying from the command line, use the passed in _artifactsLocation, otherwise use the default." + } + }, + "_artifactsLocationSasToken": { + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." + }, + "defaultValue": "" + }, + "adminVMName": { + "type": "string", + "defaultValue": "adminVM", + "metadata": { + "description": "Admin Server hosting VM name." + } + }, + "databaseType": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "One of the supported database types" + } + }, + "enablePswlessConnection": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "True to enable passwordless connection." + } + }, + "location": { + "type": "string", + "metadata": { + "description": "Location for all resources." + } + }, + "managedServerPrefix": { + "type": "string", + "defaultValue": "msp", + "metadata": { + "description": "Provide managed server prefix name" + } + }, + "managedVMNamePrefix": { + "type": "string", + "metadata": { + "description": "Managed Server hosting VM name prefix." + } + }, + "numberOfManagedApplicationInstances": { + "type": "int", + "defaultValue": 2, + "minValue": 1, + "maxValue": 20, + "metadata": { + "description": "Number of VMs that have been deployed to host managed application server." + } + }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, + "wlsDomainName": { + "type": "string", + "defaultValue": "wlsd", + "metadata": { + "description": "Provide Weblogic domain name" + } + }, + "wlsPassword": { + "type": "securestring", + "metadata": { + "description": "Password for your Weblogic domain name" + } + }, + "wlsUserName": { + "type": "string", + "metadata": { + "description": "Username for your Weblogic domain name" + } + } + }, + "variables": { + "const_managedVMPrefix": "[concat(parameters('managedVMNamePrefix'), 'VM')]", + "const_wlsAdminPort": "7005", + "const_wlsDomainPath": "[concat('/u01/domains/', parameters('wlsDomainName'))]", + "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", + "name_scriptInstallJdbcLibs": "installJdbcDrivers.sh" + }, + "resources": [ + { + "apiVersion": "${azure.apiVersionForVirtualMachines}", + "type": "Microsoft.Compute/virtualMachines/extensions", + "tags": "[parameters('tagsByResource')['${identifier.virtualMachinesExtensions}']]", + "name": "[concat(variables('const_managedVMPrefix'), copyIndex(1),'/newuserscript')]", + "location": "[parameters('location')]", + "copy": { + "name": "appVirtualMachineExtensionLoop", + "count": "[parameters('numberOfManagedApplicationInstances')]" + }, + "properties": { + "publisher": "Microsoft.Azure.Extensions", + "type": "CustomScript", + "typeHandlerVersion": "2.0", + "autoUpgradeMinorVersion": true, + "settings": { + "fileUris": [ + "[uri(parameters('_artifactsLocationInstallJdbcLibsTemplate'), concat('../scripts/', variables('name_scriptInstallJdbcLibs'), parameters('_artifactsLocationSasToken')))]" + ] + }, + "protectedSettings": { + "commandToExecute": "[concat('sh',' ',variables('name_scriptInstallJdbcLibs'),' <<< \"',variables('const_wlsHome'),' ',variables('const_wlsDomainPath'),' ',parameters('managedServerPrefix'), copyIndex(1), ' ', parameters('adminVMName'), ' ',variables('const_wlsAdminPort'),' ',parameters('wlsUserName'),' ',base64(parameters('wlsPassword')),' ',parameters('databaseType'),' ',parameters('enablePswlessConnection'), '\"')]" + } + } + } + ] +} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_keyvault/_keyvaultWithExistingCertTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_keyvault/_keyvaultWithExistingCertTemplate.json deleted file mode 100644 index 3ac6e0b13..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_keyvault/_keyvaultWithExistingCertTemplate.json +++ /dev/null @@ -1,111 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "certificateDataName": { - "type": "string", - "metadata": { - "description": "Secret name of certificate data." - } - }, - "certificateDataValue": { - "type": "string", - "metadata": { - "description": "Certificate data to store in the secret" - } - }, - "certificatePasswordName": { - "type": "string", - "metadata": { - "description": "Secret name of certificate password." - } - }, - "certificatePasswordValue": { - "type": "string", - "metadata": { - "description": "Certificate password to store in the secret" - } - }, - "enabledForTemplateDeployment": { - "type": "bool", - "metadata": { - "description": "Property to specify whether Azure Resource Manager is permitted to retrieve secrets from the key vault." - }, - "defaultValue": true - }, - "location": { - "type": "string", - "metadata": { - "description": "The supported Azure location where the key vault should be created." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Name of the vault" - } - }, - "sku": { - "type": "string", - "metadata": { - "description": "Price tier for Key Vault." - } - } - }, - "variables": {}, - "resources": [ - { - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "type": "Microsoft.KeyVault/vaults", - "properties": { - "enabledForTemplateDeployment": "[parameters('enabledForTemplateDeployment')]", - "sku": { - "name": "[parameters('sku')]", - "family": "A" - }, - "accessPolicies": [], - "tenantId": "[subscription().tenantId]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(parameters('name'), '/', parameters('certificateDataName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', parameters('name'))]" - ], - "properties": { - "value": "[parameters('certificateDataValue')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(parameters('name'), '/', parameters('certificatePasswordName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', parameters('name'))]" - ], - "properties": { - "value": "[parameters('certificatePasswordValue')]" - } - } - ], - "outputs": { - "keyVaultName": { - "type": "string", - "value": "[parameters('name')]" - }, - "sslCertDataSecretName": { - "type": "string", - "value": "[parameters('certificateDataName')]" - }, - "sslCertPwdSecretName": { - "type": "string", - "value": "[parameters('certificatePasswordName')]" - } - } -} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_keyvaultAdapterTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_keyvaultAdapterTemplate.json deleted file mode 100644 index 6297acb95..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_keyvaultAdapterTemplate.json +++ /dev/null @@ -1,212 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "_artifactsLocation": { - "type": "string", - "metadata": { - "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." - } - }, - "_artifactsLocationSasToken": { - "defaultValue": "", - "type": "securestring", - "metadata": { - "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." - } - }, - "certificateDataValue": { - "type": "securestring", - "metadata": { - "description": "Certificate data to store in the secret" - } - }, - "certificatePasswordValue": { - "type": "securestring", - "metadata": { - "description": "Certificate password to store in the secret" - } - }, - "enabledForTemplateDeployment": { - "type": "bool", - "metadata": { - "description": "Property to specify whether Azure Resource Manager is permitted to retrieve secrets from the key vault." - }, - "defaultValue": true - }, - "identity": { - "type": "object" - }, - "location": { - "type": "string", - "metadata": { - "description": "Location for all resources." - } - }, - "permission": { - "type": "object", - "defaultValue": { - "certificates": [ - "get", - "list", - "update", - "create" - ] - } - }, - "sku": { - "type": "string", - "metadata": { - "description": "Price tier for Key Vault." - }, - "defaultValue": "Standard" - }, - "subjectName": { - "type": "string", - "metadata": { - "description": "Subject name to create a certificate." - } - }, - "useExistingAppGatewaySSLCertificate": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "If false, will create a certificate." - } - }, - "keyVaultName": { - "type": "string", - "defaultValue": "GEN_UNIQUE", - "metadata": { - "description": "Current deployment time. Used as a tag in deployment script." - } - } - }, - "variables": { - "name_kvWithExistingCertTemplateName": "_keyvaultWithExistingCertTemplate.json", - "name_kvWithNewCertTemplateName": "_keyvaultWithNewCertTemplate.json", - "name_kvTempaltesFolder": "_keyvault", - "name_sslCertSecretName": "myAppGatewaySSLCert", - "name_sslCertPasswordSecretName": "myAppGatewaySSLCertPassword" - }, - "resources": [ - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${cluster.appgateway.keyvault.start}", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - }, - { - "apiVersion": "${azure.apiVersionForDeploymentScript}", - "type": "Microsoft.Resources/deployments", - "name": "keyVaultwithSelfSignedAppGatewaySSLCert", - "condition": "[not(parameters('useExistingAppGatewaySSLCertificate'))]", - "properties": { - "mode": "Incremental", - "templateLink": { - "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_kvTempaltesFolder'),'/', variables('name_kvWithNewCertTemplateName'), parameters('_artifactsLocationSasToken')))]", - "contentVersion": "1.0.0.0" - }, - "parameters": { - "identity": { - "value": "[parameters('identity')]" - }, - "keyvaultName": { - "value": "[parameters('keyVaultName')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "permission": { - "value": "[parameters('permission')]" - }, - "subjectName": { - "value": "[parameters('subjectName')]" - }, - "sku": { - "value": "[parameters('sku')]" - } - } - } - }, - { - "apiVersion": "${azure.apiVersionForDeploymentScript}", - "type": "Microsoft.Resources/deployments", - "name": "keyVaultwithExistingAppGatewaySSLCert", - "condition": "[parameters('useExistingAppGatewaySSLCertificate')]", - "properties": { - "mode": "Incremental", - "templateLink": { - "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_kvTempaltesFolder'),'/', variables('name_kvWithExistingCertTemplateName'), parameters('_artifactsLocationSasToken')))]", - "contentVersion": "1.0.0.0" - }, - "parameters": { - "certificateDataName": { - "value": "[variables('name_sslCertSecretName')]" - }, - "certificateDataValue": { - "value": "[parameters('certificateDataValue')]" - }, - "certificatePasswordName": { - "value": "[variables('name_sslCertPasswordSecretName')]" - }, - "certificatePasswordValue": { - "value": "[parameters('certificatePasswordValue')]" - }, - "enabledForTemplateDeployment": { - "value": "[parameters('enabledForTemplateDeployment')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "name": { - "value": "[parameters('keyVaultName')]" - }, - "sku": { - "value": "[parameters('sku')]" - } - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${cluster.appgateway.keyvault.end}", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - } - ], - "outputs": { - "_artifactsLocation": { - "type": "string", - "value": "[parameters('_artifactsLocation')]" - }, - "keyVaultName": { - "type": "string", - "value": "[if(parameters('useExistingAppGatewaySSLCertificate'), reference('keyVaultwithExistingAppGatewaySSLCert', '${azure.apiVersion}').outputs.keyvaultName.value, reference('keyVaultwithSelfSignedAppGatewaySSLCert', '${azure.apiVersion}').outputs.keyvaultName.value)]" - }, - "sslCertDataSecretName": { - "type": "string", - "value": "[if(parameters('useExistingAppGatewaySSLCertificate'), reference('keyVaultwithExistingAppGatewaySSLCert', '${azure.apiVersion}').outputs.sslCertDataSecretName.value, reference('keyVaultwithSelfSignedAppGatewaySSLCert', '${azure.apiVersion}').outputs.secretName.value)]" - }, - "sslCertPwdSecretName": { - "type": "string", - "value": "[if(parameters('useExistingAppGatewaySSLCertificate'), reference('keyVaultwithExistingAppGatewaySSLCert', '${azure.apiVersion}').outputs.sslCertPwdSecretName.value, '')]" - } - } -} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_keyvaultSSLConfigTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_keyvaultSSLConfigTemplate.json deleted file mode 100644 index c83683205..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_keyvaultSSLConfigTemplate.json +++ /dev/null @@ -1,196 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "uploadedCustomIdentityKeyStoreData": { - "type": "string", - "metadata": { - "description": "Custom Identity KeyStore Data" - } - }, - "uploadedCustomIdentityKeyStorePassphrase": { - "type": "securestring", - "metadata": { - "description": "Custom Identity KeyStore Passphrase" - } - }, - "uploadedCustomTrustKeyStoreData": { - "type": "securestring", - "metadata": { - "description": "Custom Trust KeyStore Data" - } - }, - "uploadedCustomTrustKeyStorePassPhrase": { - "type": "securestring", - "metadata": { - "description": "Custom Trust KeyStore PassPhrase" - } - }, - "uploadedPrivateKeyAlias": { - "type": "string", - "metadata": { - "description": "Alias of the private key" - } - }, - "uploadedPrivateKeyPassPhrase": { - "type": "securestring", - "metadata": { - "description": "Password of the private key" - } - }, - "enabledForTemplateDeployment": { - "type": "bool", - "metadata": { - "description": "Property to specify whether Azure Resource Manager is permitted to retrieve secrets from the key vault." - }, - "defaultValue": true - }, - "location": { - "type": "string", - "metadata": { - "description": "The supported Azure location where the key vault should be created." - } - }, - "sku": { - "type": "string", - "metadata": { - "description": "Price tier for Key Vault." - }, - "defaultValue": "Standard" - }, - "keyVaultName": { - "type": "string", - "defaultValue": "GEN_UNIQUE", - "metadata": { - "description": "Current deployment time. Used as a tag in deployment script." - } - } - }, - "variables": { - "name_customIdentityKeyStoreDataSecretName": "customIdentityKeyStoreData", - "name_customIdentityKeyStorePassPhraseSecretName": "customIdentityKeyStorePassPhrase", - "name_customTrustKeyStoreDataSecretName": "customTrustKeyStoreData", - "name_customTrustKeyStorePassPhraseSecretName": "customTrustKeyStorePassPhrase", - "name_privateKeyAliasSecretName": "privateKeyAlias", - "name_privateKeyPassPhraseSecretName": "privateKeyPassPhrase" - }, - "resources": [ - { - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[parameters('keyVaultName')]", - "location": "[parameters('location')]", - "type": "Microsoft.KeyVault/vaults", - "properties": { - "enabledForTemplateDeployment": "[parameters('enabledForTemplateDeployment')]", - "sku": { - "name": "[parameters('sku')]", - "family": "A" - }, - "accessPolicies": [], - "tenantId": "[subscription().tenantId]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(parameters('keyVaultName'), '/', variables('name_customIdentityKeyStoreDataSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedCustomIdentityKeyStoreData')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(parameters('keyVaultName'), '/', variables('name_customIdentityKeyStorePassPhraseSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedCustomIdentityKeyStorePassphrase')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(parameters('keyVaultName'), '/', variables('name_customTrustKeyStoreDataSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedCustomTrustKeyStoreData')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(parameters('keyVaultName'), '/', variables('name_customTrustKeyStorePassPhraseSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedCustomTrustKeyStorePassPhrase')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(parameters('keyVaultName'), '/', variables('name_privateKeyAliasSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedPrivateKeyAlias')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(parameters('keyVaultName'), '/', variables('name_privateKeyPassPhraseSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedPrivateKeyPassPhrase')]" - } - } - ], - "outputs": { - "keyVaultName": { - "type": "string", - "value": "[parameters('keyVaultName')]" - }, - "customIdentityKeyStoreDataSecretName": { - "type": "string", - "value": "[variables('name_customIdentityKeyStoreDataSecretName')]" - }, - "customIdentityKeyStorePassPhraseSecretName": { - "type": "string", - "value": "[variables('name_customIdentityKeyStorePassPhraseSecretName')]" - }, - "customTrustKeyStoretDataSecretName": { - "type": "string", - "value": "[variables('name_customTrustKeyStoreDataSecretName')]" - }, - "customTrustKeyStorePassPhraseSecretName": { - "type": "string", - "value": "[variables('name_customTrustKeyStorePassPhraseSecretName')]" - }, - "privateKeyAliasSecretName": { - "type": "string", - "value": "[variables('name_privateKeyAliasSecretName')]" - }, - "privateKeyPassPhraseSecretName": { - "type": "string", - "value": "[variables('name_privateKeyPassPhraseSecretName')]" - } - } -} \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_keyvault/_keyvaultWithNewCertTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_keyvaultWithNewCertTemplate.json similarity index 60% rename from weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_keyvault/_keyvaultWithNewCertTemplate.json rename to weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_keyvaultWithNewCertTemplate.json index c780a6352..87c767643 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_keyvault/_keyvaultWithNewCertTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_keyvaultWithNewCertTemplate.json @@ -2,10 +2,10 @@ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { - "identity": { - "type": "object", + "_globalResourceNameSuffix": { + "type": "string", "metadata": { - "description": "Managed identity to be used for the deployment script. Currently, only user-assigned MSI is supported." + "description": "A unique suffix that was specified during the deployment of the solution template." } }, "keyvaultName": { @@ -55,37 +55,53 @@ "description": "Subject name to create a new certificate, example: 'CN=contoso.com'." } }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, "utcValue": { "type": "string", "defaultValue": "[utcNow()]" } }, - "functions": [ - { - "namespace": "identity", - "members": { - "getId": { - "parameters": [ - { - "name": "items", - "type": "object" - } - ], - "output": { - "type": "string", - "value": "[if(empty(parameters('items').userAssignedIdentities), '', substring(string(parameters('items').userAssignedIdentities),add(indexOf(string(parameters('items').userAssignedIdentities),'\"'),1),sub(lastIndexOf(string(parameters('items').userAssignedIdentities), '\"'),add(indexOf(string(parameters('items').userAssignedIdentities),'\"'),1))))]" - } - } - } - } - ], "variables": { + "const_roleDefinitionIdOfContributor": "b24988ac-6180-42a0-ab88-20f7382dd24c", + "name_deploymentScriptUserDefinedManagedIdentity": "[concat('wls-vm-keyvault-user-defined-managed-itentity', parameters('_globalResourceNameSuffix'))]", + "name_roleAssignmentName": "[guid(format('{0}{1}Role assignment in resource group scope', subscription().id, parameters('utcValue')))]" }, "resources": [ + { + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "${azure.apiVersionForIdentity}", + "tags": "[parameters('tagsByResource')['${identifier.userAssignedIdentities}']]", + "name": "[variables('name_deploymentScriptUserDefinedManagedIdentity')]", + "location": "[parameters('location')]" + }, + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "${azure.apiVersionForRoleAssignment}", + "name": "[variables('name_roleAssignmentName')]", + "dependsOn": [ + "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('name_deploymentScriptUserDefinedManagedIdentity'))]" + ], + "properties": { + "description": "Assign subscription scope role to User Assigned Managed Identity ", + "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities',variables('name_deploymentScriptUserDefinedManagedIdentity'))).principalId]", + "principalType": "ServicePrincipal", + "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', variables('const_roleDefinitionIdOfContributor'))]" + } + }, { "type": "Microsoft.KeyVault/vaults", "apiVersion": "${azure.apiVersionForKeyVault}", + "tags": "[parameters('tagsByResource')['${identifier.vaults}']]", "name": "[parameters('keyvaultName')]", + "dependsOn": [ + "[resourceId('Microsoft.Authorization/roleAssignments', variables('name_roleAssignmentName'))]" + ], "location": "[parameters('location')]", "properties": { "sku": { @@ -95,7 +111,7 @@ "tenantId": "[subscription().tenantId]", "accessPolicies": [ { - "objectId": "[reference(string(identity.getId(parameters('identity'))), '${azure.apiVersionForIndentity}').principalId]", + "objectId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('name_deploymentScriptUserDefinedManagedIdentity'))).principalId]", "tenantId": "[subscription().tenantId]", "permissions": "[parameters('permission')]" } @@ -103,24 +119,41 @@ "enabledForDeployment": false, "enabledForDiskEncryption": false, "enabledForTemplateDeployment": true, - "enableSoftDelete": true + "enableSoftDelete": true, + "enableRbacAuthorization": false } }, { "type": "Microsoft.Resources/deploymentScripts", "apiVersion": "${azure.apiVersionForDeploymentScript}", - "name": "script-createAddCertificate", + "tags": "[parameters('tagsByResource')['${identifier.deploymentScripts}']]", + "name": "[concat('script-generate-certificate-', parameters('_globalResourceNameSuffix'))]", "location": "[parameters('location')]", "dependsOn": [ "[resourceId('Microsoft.KeyVault/vaults', parameters('keyvaultName'))]" ], - "identity": "[parameters('identity')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('name_deploymentScriptUserDefinedManagedIdentity'))]": {} + } + }, "kind": "AzurePowerShell", "properties": { "forceUpdateTag": "[parameters('utcValue')]", - "azPowerShellVersion": "5.0", + "azPowerShellVersion": "${azure.powershell.version}", "timeout": "PT30M", "arguments": "[format(' -vaultName {0} -certificateName {1} -subjectName {2}', parameters('keyvaultName'), parameters('secretName'), parameters('subjectName'))]", + "environmentVariables": [ + { + "name": "MANAGED_IDENTITY_ID", + "value": "[variables('name_deploymentScriptUserDefinedManagedIdentity')]" + }, + { + "name": "RESOURCE_GROUP_NAME", + "value": "[resourceGroup().name]" + } + ], "scriptContent": " param( [string] [Parameter(Mandatory=$true)] $vaultName, @@ -170,6 +203,13 @@ $DeploymentScriptOutputs['certThumbprint'] = $newCert.Thumbprint $newCert | Out-String } + + # Do not load MSI module to resolve issue 288. It's loaded by default in new PowerShell. + # Install-Module -Name Az.ManagedServiceIdentity -AllowClobber -Force + # delete user assigned managed identity. + $identityName = [System.Environment]::GetEnvironmentVariable('MANAGED_IDENTITY_ID') + $resourceGroupName= [System.Environment]::GetEnvironmentVariable('RESOURCE_GROUP_NAME') + Get-AzUserAssignedIdentity -ResourceGroupName $resourceGroupName -Name $identityName | Remove-AzUserAssignedIdentity ", "cleanupPreference": "OnSuccess", "retentionInterval": "P1D" @@ -186,4 +226,4 @@ "value": "[parameters('secretName')]" } } -} +} \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_pswlessDbTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_pswlessDbTemplate.json new file mode 100644 index 000000000..7eb7112ad --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/_pswlessDbTemplate.json @@ -0,0 +1,340 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." + } + }, + "_artifactsLocationSasToken": { + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." + }, + "defaultValue": "" + }, + "adminVMName": { + "type": "string", + "defaultValue": "adminVM", + "metadata": { + "description": "Admin Server hosting VM name." + } + }, + "databaseType": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "One of the supported database types" + } + }, + "dbGlobalTranPro": { + "defaultValue": "OnePhaseCommit", + "type": "string", + "metadata": { + "description": "Determines the transaction protocol (global transaction processing behavior) for the data source." + } + }, + "dbIdentity": { + "defaultValue": {}, + "type": "object", + "metadata": { + "description": "Managed identity that has access to the data source." + } + }, + "dbUser": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Userid of Database" + } + }, + "dsConnectionURL": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "JDBC Connection String" + } + }, + "jdbcDataSourceName": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "JNDI Name for JDBC Datasource" + } + }, + "location": { + "type": "string", + "metadata": { + "description": "Location for all resources." + } + }, + "managedServerPrefix": { + "type": "string", + "defaultValue": "msp", + "metadata": { + "description": "Provide managed server prefix name" + } + }, + "managedVMNamePrefix": { + "type": "string", + "metadata": { + "description": "Provide managed VM name prefix" + } + }, + "numberOfManagedApplicationInstances": { + "type": "int", + "defaultValue": 2, + "minValue": 1, + "maxValue": 20, + "metadata": { + "description": "Number of VMs that have been deployed to host managed application server." + } + }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, + "wlsDomainName": { + "type": "string", + "defaultValue": "wlsd", + "metadata": { + "description": "Provide Weblogic domain name" + } + }, + "wlsPassword": { + "type": "securestring", + "metadata": { + "description": "Password for your Weblogic domain name" + } + }, + "wlsUserName": { + "type": "string", + "metadata": { + "description": "Username for your Weblogic domain name" + } + } + }, + "variables": { + "const_connectionString": "[if(and(equals(parameters('databaseType'),'sqlserver'), equals(last(parameters('dsConnectionURL')),';')), take(parameters('dsConnectionURL'), add(length(parameters('dsConnectionURL')),-1)),parameters('dsConnectionURL'))]", + "const_identityAPIVersion": "${azure.apiVersionForIdentity}", + "const_managedVMPrefix": "[concat(parameters('managedVMNamePrefix'), 'VM')]", + "const_msiDefaultUser": "msiUser", + "name_appendIdentityTemplate": "_appendUserManagedIdentity.json", + "name_installJdbcLibsTemplate": "_installJdbcLibsTemplate.json", + "name_dbTemplate": "_dbTemplate.json", + "array_azureJdbcPlugins": { + "mysql": "defaultAuthenticationPlugin=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin&authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin", + "postgresql": "authenticationPluginClassName=com.azure.identity.extensions.jdbc.postgresql.AzurePostgresqlAuthenticationPlugin", + "sqlserver": "authentication=ActiveDirectoryMSI" + }, + "array_urlJoiner": { + "mysql": "[if(contains(variables('const_connectionString'), '?'), '&', '?')]", + "postgresql": "[if(contains(variables('const_connectionString'), '?'), '&', '?')]", + "sqlserver": ";" + }, + "array_paramJoiner": { + "mysql": "&", + "postgresql": "&", + "sqlserver": ";" + }, + "array_msiClientId": { + "mysql": "azure.clientId", + "postgresql": "azure.clientId", + "sqlserver": "msiClientId" + }, + "obj_dbIdentity": { + "[items(parameters('dbIdentity').userAssignedIdentities)[0].key]": {} + }, + "obj_empty": {} + }, + "resources": [ + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${cluster.pswless.database.start}", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "[concat('assignDbIdentityTo',variables('const_managedVMPrefix'), copyIndex(1))]", + "copy": { + "name": "virtualMachineIdentityLoop", + "count": "[parameters('numberOfManagedApplicationInstances')]" + }, + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_appendIdentityTemplate')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "vmName": { + "value": "[concat(variables('const_managedVMPrefix'), copyIndex(1))]" + }, + "newIdentities": { + "value": "[variables('obj_dbIdentity')]" + }, + "existingIdentities": { + "value": "[if(equals(reference(resourceId('Microsoft.Compute/virtualMachines',concat(variables('const_managedVMPrefix'), copyIndex(1))), '${azure.apiVersionForVirtualMachines}', 'Full').identity.type,'UserAssigned'),reference(resourceId('Microsoft.Compute/virtualMachines',concat(variables('const_managedVMPrefix'), copyIndex(1))), '${azure.apiVersionForVirtualMachines}', 'Full').identity.userAssignedIdentities, variables('obj_empty'))]" + }, + "location": { + "value": "[parameters('location')]" + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "installJdbcLibsTemplate", + "condition": "[or(equals(parameters('databaseType'),'mysql'), equals(parameters('databaseType'),'postgresql'))]", + "dependsOn": [ + "virtualMachineIdentityLoop" + ], + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_installJdbcLibsTemplate')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + }, + "adminVMName": { + "value": "[parameters('adminVMName')]" + }, + "databaseType": { + "value": "[parameters('databaseType')]" + }, + "enablePswlessConnection": { + "value": true + }, + "location": { + "value": "[parameters('location')]" + }, + "managedServerPrefix": { + "value": "[parameters('managedServerPrefix')]" + }, + "managedVMNamePrefix": { + "value": "[parameters('managedVMNamePrefix')]" + }, + "numberOfManagedApplicationInstances": { + "value": "[parameters('numberOfManagedApplicationInstances')]" + }, + "tagsByResource": { + "value": "[parameters('tagsByResource')]" + }, + "wlsDomainName": { + "value": "[parameters('wlsDomainName')]" + }, + "wlsPassword": { + "value": "[parameters('wlsPassword')]" + }, + "wlsUserName": { + "value": "[parameters('wlsUserName')]" + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "passwordlessDatasourceDeployment", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'installJdbcLibsTemplate')]" + ], + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_dbTemplate')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + }, + "adminVMName": { + "value": "[parameters('adminVMName')]" + }, + "databaseType": { + "value": "[parameters('databaseType')]" + }, + "dbGlobalTranPro": { + "value": "[parameters('dbGlobalTranPro')]" + }, + "dsConnectionURL": { + "value": "[uri(format('{0}{4}{1}{5}{2}={3}', variables('const_connectionString'), variables('array_azureJdbcPlugins')[parameters('databaseType')], variables('array_msiClientId')[parameters('databaseType')], reference(items(parameters('dbIdentity').userAssignedIdentities)[0].key,variables('const_identityAPIVersion'), 'full').properties.clientId, variables('array_urlJoiner')[parameters('databaseType')], variables('array_paramJoiner')[parameters('databaseType')]), '')]" + }, + "dbUser": { + "value": "[if(equals(parameters('databaseType'), 'sqlserver'), variables('const_msiDefaultUser'), parameters('dbUser'))]" + }, + "enablePswlessConnection": { + "value": true + }, + "jdbcDataSourceName": { + "value": "[parameters('jdbcDataSourceName')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "tagsByResource": { + "value": "[parameters('tagsByResource')]" + }, + "wlsPassword": { + "value": "[parameters('wlsPassword')]" + }, + "wlsUserName": { + "value": "[parameters('wlsUserName')]" + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${cluster.pswless.database.end}", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'passwordlessDatasourceDeployment')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + } + ], + "outputs": { + "artifactsLocationPassedIn": { + "type": "string", + "value": "[parameters('_artifactsLocation')]" + } + } +} \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/aadNestedTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/aadNestedTemplate.json deleted file mode 100644 index 11512a0c4..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/aadNestedTemplate.json +++ /dev/null @@ -1,251 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "_artifactsLocation": { - "type": "string", - "metadata": { - "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." - } - }, - "_artifactsLocationAADTemplate": { - "defaultValue": "[if(contains(parameters('_artifactsLocation'), 'githubusercontent'), parameters('_artifactsLocation'), deployment().properties.templateLink.uri)]", - "type": "string", - "metadata": { - "description": "If we are deploying from the command line, use the passed in _artifactsLocation, otherwise use the default." - } - }, - "_artifactsLocationSasToken": { - "defaultValue": "", - "type": "securestring", - "metadata": { - "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." - } - }, - "aadsPortNumber": { - "defaultValue": "636", - "type": "string", - "metadata": { - "description": "Accessible port of the LDAP server." - } - }, - "aadsPublicIP": { - "defaultValue": "The LDAP server public IP address", - "type": "string" - }, - "aadsServerHost": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "The LDAP server host." - } - }, - "adminVMName": { - "defaultValue": "adminVM", - "type": "string", - "metadata": { - "description": "Admin Server hosting VM name." - } - }, - "location": { - "type": "string", - "metadata": { - "description": "Location for all resources." - } - }, - "managedServerPrefix": { - "type": "string", - "defaultValue": "msp", - "metadata": { - "description": "Provide managed server prefix name" - } - }, - "numberOfInstances": { - "type": "int", - "defaultValue": 2, - "minValue": 2, - "maxValue": 5, - "metadata": { - "description": "Number of VMs to deploy, limit 5 since this sample is using a single storage account" - } - }, - "wlsDomainName": { - "defaultValue": "wlsd", - "type": "string", - "metadata": { - "description": "Provide Weblogic domain name" - } - }, - "wlsLDAPGroupBaseDN": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "The base distinguished name (DN) of the tree in the LDAP directory that contains groups." - } - }, - "wlsLDAPPrincipal": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "The Distinguished Name (DN) of the LDAP user that WebLogic Server should use to connect to the LDAP server." - } - }, - "wlsLDAPPrincipalPassword": { - "defaultValue": "[newGuid()]", - "type": "securestring", - "metadata": { - "description": "The credential (usually a password) used to connect to the LDAP server." - } - }, - "wlsLDAPProviderName": { - "defaultValue": "AzureActiveDirectoryProvider", - "type": "string", - "metadata": { - "description": "The value used for creating authentication provider name of WebLogic Server." - } - }, - "wlsLDAPSSLCertificate": { - "defaultValue": "", - "type": "securestring", - "metadata": { - "description": "Client certificate that will be imported to trust store of SSL." - } - }, - "wlsLDAPUserBaseDN": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "The base distinguished name (DN) of the tree in the LDAP directory that contains users." - } - }, - "wlsPassword": { - "type": "securestring", - "metadata": { - "description": "Password for your Weblogic domain name" - } - }, - "wlsUserName": { - "defaultValue": "weblogic", - "type": "string", - "metadata": { - "description": "Username for your Weblogic domain name" - } - }, - "enableCustomSSL": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Boolean value indicating, if custom SSL is enabled or not" - } - }, - "keyVaultCustomTrustKeyStorePassPhrase": { - "type": "securestring", - "defaultValue": "", - "metadata": { - "description": "Weblogic Custom Trust Store Passphrase" - } - }, - "keyVaultCustomTrustKeyStoreType": { - "type": "string", - "defaultValue": "null", - "metadata": { - "description": "Weblogic Custom Trust Store Type (JKS or PKCS12)" - } - } - }, - "variables": { - "const_aadParameters": "[concat(parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('wlsDomainName'),' ',parameters('wlsLDAPProviderName'), ' ', parameters('aadsServerHost'), ' ', parameters('aadsPortNumber'), ' ', concat('\"',parameters('wlsLDAPPrincipal'),'\"'), ' ', parameters('wlsLDAPPrincipalPassword'), ' ', concat('\"',parameters('wlsLDAPUserBaseDN'),'\"'), ' ', concat('\"',parameters('wlsLDAPGroupBaseDN'),'\"'), ' ', variables('const_wlsHome'),' ',parameters('adminVMName'),' ',variables('const_wlsAdminPort'),' ',parameters('wlsLDAPSSLCertificate'), ' ', parameters('aadsPublicIP'), ' ',variables('const_adminServerName'), ' ', variables('const_wlsDomainPath'),' ',parameters('enableCustomSSL'),' ',base64(parameters('keyVaultCustomTrustKeyStorePassPhrase')),' ',base64(parameters('keyVaultCustomTrustKeyStoreType')))]", - "const_adminServerName": "admin", - "const_managedVMPrefix": "[concat(parameters('managedServerPrefix'),'VM')]", - "const_wlsAdminPort": "7005", - "const_wlsDomainPath": "[concat('/u01/domains/', parameters('wlsDomainName'))]", - "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", - "name_scriptAADConfiguration": "aadIntegration.sh" - }, - "resources": [ - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${cluster.aad.start}", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(variables('const_managedVMPrefix'), add(copyIndex(), 1),'/newuserscript')]", - "location": "[parameters('location')]", - "copy": { - "name": "managedVirtualMachineExtensionLoop", - "count": "[add(parameters('numberOfInstances'), -1)]" - }, - "properties": { - "publisher": "Microsoft.Azure.Extensions", - "type": "CustomScript", - "typeHandlerVersion": "2.0", - "autoUpgradeMinorVersion": true, - "settings": { - "fileUris": [ - "[uri(parameters('_artifactsLocationAADTemplate'), concat('../scripts/', variables('name_scriptAADConfiguration'), parameters('_artifactsLocationSasToken')))]" - ] - }, - "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptAADConfiguration'),' <<< \"', variables('const_aadParameters'),' ', add(copyIndex(),1),'\"')]" - } - } - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(parameters('adminVMName'),'/newuserscript')]", - "location": "[parameters('location')]", - "dependsOn": [ - "managedVirtualMachineExtensionLoop" - ], - "properties": { - "publisher": "Microsoft.Azure.Extensions", - "type": "CustomScript", - "typeHandlerVersion": "2.0", - "autoUpgradeMinorVersion": true, - "settings": { - "fileUris": [ - "[uri(parameters('_artifactsLocationAADTemplate'), concat('../scripts/', variables('name_scriptAADConfiguration'), parameters('_artifactsLocationSasToken')))]" - ] - }, - "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptAADConfiguration'),' <<< \"', variables('const_aadParameters'),' ', 0,'\"')]" - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${cluster.aad.end}", - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" - ], - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - } - ], - "outputs": { - "artifactsLocationPassedIn": { - "type": "string", - "value": "[parameters('_artifactsLocation')]" - } - } -} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/appGatewayNestedTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/appGatewayNestedTemplate.json index db77166e5..74a24fc17 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/appGatewayNestedTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/appGatewayNestedTemplate.json @@ -29,6 +29,15 @@ "description": "Admin Server hosting VM name." } }, + "appGatewayName": { + "type": "string", + "metadata": { + "description": "Application Gateway name" + } + }, + "appGatewaySSLBackendCertData": { + "type": "securestring" + }, "appGatewaySSLCertificateData": { "type": "securestring" }, @@ -49,6 +58,17 @@ "description": "DNS for ApplicationGateway" } }, + "enableCookieBasedAffinity": { + "defaultValue": true, + "type": "bool", + "metadata": { + "description": "true to enable cookie based affinity." + } + }, + "enableCustomSSL": { + "defaultValue": false, + "type": "bool" + }, "gatewayPublicIPAddressName": { "defaultValue": "gwip", "type": "string", @@ -66,11 +86,10 @@ "description": "Location for all resources." } }, - "managedServerPrefix": { - "defaultValue": "msp", + "managedVMNamePrefix": { "type": "string", "metadata": { - "description": "Provide managed server prefix names" + "description": "Managed Server hosting VM name prefix." } }, "numberOfInstances": { @@ -89,6 +108,45 @@ "description": "If true, will override the host name with dnszoneSubDomain." } }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, + "virtualNetworkNewOrExisting": { + "type": "string", + "defaultValue": "new", + "allowedValues": [ + "new", + "existing" + ], + "metadata": { + "description": "Specify whether to create a new or existing virtual network for the VM." + } + }, + "virtualNetworkName": { + "type": "string", + "defaultValue": "wls-vnet", + "metadata": { + "description": "Name of the existing or new VNET" + } + }, + "virtualNetworkResourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "Resource group of Virtual network" + } + }, + "subnetForAppGateway": { + "type": "string", + "defaultValue": "appgateway-subnet", + "metadata": { + "description": "Name of the existing or new Subnet for Application Gateway" + } + }, "wlsDomainName": { "defaultValue": "wlsd", "type": "string", @@ -115,12 +173,12 @@ "const_appGatewayFrontEndHTTPPort": 80, "const_appGatewayFrontEndHTTPSPort": 443, "const_backendPort": 8001, - "const_managedVMPrefix": "[concat(parameters('managedServerPrefix'),'VM')]", + "name_nic_with_pub_ip": "_NIC_with_pub_ip", + "name_nic_without_pub_ip": "_NIC_without_pub_ip", "const_wlsAdminPort": "7005", "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", - "name_appGateway": "myAppGateway", "name_appGatewayCertificate": "appGwSslCertificate", - "name_appGatewaySubnet": "appGatewaySubnet", + "name_appGatewaySubnet": "[parameters('subnetForAppGateway')]", "name_backendAddressPool": "myGatewayBackendPool", "name_frontEndIPConfig": "appGwPublicFrontendIp", "name_httpListener": "HTTPListener", @@ -128,14 +186,23 @@ "name_httpSetting": "myHTTPSetting", "name_httpsListener": "HTTPSListener", "name_httpsPort": "https_port", + "name_managedVMNamePrefix": "[concat(parameters('managedVMNamePrefix'),'VM')]", "name_probe": "HTTPhealthProbe", "name_scriptAGWConfiguration": "setupApplicationGateway.sh", - "name_virtualNetwork": "[concat(parameters('wlsDomainName'),'_VNET')]", + "name_virtualNetwork": "[parameters('virtualNetworkName')]", + "obj_backendTrustedRootCerts": [ + { + "name": "appGatewayTrustedRootCert", + "properties": { + "data": "[parameters('appGatewaySSLBackendCertData')]" + } + } + ], "obj_HTTPSettingsDefault": { "provisioningState": "Succeeded", "port": "[int(variables('const_backendPort'))]", "protocol": "Http", - "cookieBasedAffinity": "Enabled", + "cookieBasedAffinity": "[if(parameters('enableCookieBasedAffinity'), 'Enabled', 'Disabled')]", "pickHostNameFromBackendAddress": true, "affinityCookieName": "ApplicationGatewayAffinity", "requestTimeout": 20, @@ -147,7 +214,7 @@ "provisioningState": "Succeeded", "port": "[int(variables('const_backendPort'))]", "protocol": "Http", - "cookieBasedAffinity": "Enabled", + "cookieBasedAffinity": "[if(parameters('enableCookieBasedAffinity'), 'Enabled', 'Disabled')]", "hostName": "[parameters('customDomainName')]", "pickHostNameFromBackendAddress": false, "affinityCookieName": "ApplicationGatewayAffinity", @@ -157,21 +224,22 @@ } }, "ref_appGatewayPublicIP": "[resourceId('Microsoft.Network/publicIPAddresses',parameters('gatewayPublicIPAddressName'))]", - "ref_appGatewaySubnet": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_appGatewaySubnet'))]", - "ref_backendAddressPool": "[resourceId('Microsoft.Network/applicationGateways/backendAddressPools', variables('name_appGateway'),variables('name_backendAddressPool'))]", - "ref_backendHttpSettings": "[resourceId('Microsoft.Network/applicationGateways/backendHttpSettingsCollection', variables('name_appGateway'),variables('name_httpSetting'))]", - "ref_backendProbe": "[resourceId('Microsoft.Network/applicationGateways/probes', variables('name_appGateway'),variables('name_probe'))]", - "ref_frontendHTTPPort": "[resourceId('Microsoft.Network/applicationGateways/frontendPorts', variables('name_appGateway'),variables('name_httpPort'))]", - "ref_frontendHTTPSPort": "[resourceId('Microsoft.Network/applicationGateways/frontendPorts', variables('name_appGateway'),variables('name_httpsPort'))]", - "ref_frontendIPConfiguration": "[resourceId('Microsoft.Network/applicationGateways/frontendIPConfigurations', variables('name_appGateway'),variables('name_frontEndIPConfig'))]", - "ref_httpListener": "[resourceId('Microsoft.Network/applicationGateways/httpListeners', variables('name_appGateway'),variables('name_httpListener'))]", - "ref_httpsListener": "[resourceId('Microsoft.Network/applicationGateways/httpListeners', variables('name_appGateway'),variables('name_httpsListener'))]", - "ref_sslCertificate": "[resourceId('Microsoft.Network/applicationGateways/sslCertificates', variables('name_appGateway'),variables('name_appGatewayCertificate'))]" + "ref_appGatewaySubnet": "[resourceId(parameters('virtualNetworkResourceGroupName'),'Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_appGatewaySubnet'))]", + "ref_backendAddressPool": "[resourceId('Microsoft.Network/applicationGateways/backendAddressPools', parameters('appGatewayName'),variables('name_backendAddressPool'))]", + "ref_backendHttpSettings": "[resourceId('Microsoft.Network/applicationGateways/backendHttpSettingsCollection', parameters('appGatewayName'),variables('name_httpSetting'))]", + "ref_backendProbe": "[resourceId('Microsoft.Network/applicationGateways/probes', parameters('appGatewayName'),variables('name_probe'))]", + "ref_frontendHTTPPort": "[resourceId('Microsoft.Network/applicationGateways/frontendPorts', parameters('appGatewayName'),variables('name_httpPort'))]", + "ref_frontendHTTPSPort": "[resourceId('Microsoft.Network/applicationGateways/frontendPorts', parameters('appGatewayName'),variables('name_httpsPort'))]", + "ref_frontendIPConfiguration": "[resourceId('Microsoft.Network/applicationGateways/frontendIPConfigurations', parameters('appGatewayName'),variables('name_frontEndIPConfig'))]", + "ref_httpListener": "[resourceId('Microsoft.Network/applicationGateways/httpListeners', parameters('appGatewayName'),variables('name_httpListener'))]", + "ref_httpsListener": "[resourceId('Microsoft.Network/applicationGateways/httpListeners', parameters('appGatewayName'),variables('name_httpsListener'))]", + "ref_sslCertificate": "[resourceId('Microsoft.Network/applicationGateways/sslCertificates', parameters('appGatewayName'),variables('name_appGatewayCertificate'))]" }, "resources": [ { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "name": "${cluster.appgateway.start}", "properties": { "mode": "Incremental", @@ -184,8 +252,9 @@ } }, { + "apiVersion": "${azure.apiVersionForPublicIPAddresses}", "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "${azure.apiVersion}", + "tags": "[parameters('tagsByResource')['${identifier.publicIPAddresses}']]", "name": "[parameters('gatewayPublicIPAddressName')]", "sku": { "name": "Standard" @@ -200,8 +269,9 @@ }, { "type": "Microsoft.Network/applicationGateways", - "apiVersion": "${azure.apiVersion}", - "name": "[variables('name_appGateway')]", + "apiVersion": "${azure.apiVersionForApplicationGateways}", + "tags": "[parameters('tagsByResource')['${identifier.applicationGateways}']]", + "name": "[parameters('appGatewayName')]", "location": "[parameters('location')]", "dependsOn": [ "[resourceId('Microsoft.Network/publicIPAddresses', parameters('gatewayPublicIPAddressName'))]" @@ -258,6 +328,7 @@ } } ], + "trustedRootCertificates": "[if(parameters('enableCustomSSL'),variables('obj_backendTrustedRootCerts'), '[]')]", "backendAddressPools": [ { "name": "myGatewayBackendPool", @@ -267,7 +338,7 @@ "name": "BackendAddresses", "count": "[sub(int(parameters('numberOfInstances')),1)]", "input": { - "fqdn": "[concat(variables('const_managedVMPrefix'), copyIndex('BackendAddresses',1))]" + "ipAddress": "[reference(resourceId('Microsoft.Network/networkInterfaces', concat(variables('name_managedVMNamePrefix'), copyIndex('BackendAddresses',1), if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), variables('name_nic_with_pub_ip'), variables('name_nic_without_pub_ip')))),'${azure.apiVersionForNetworkInterfaces}').ipConfigurations[0].properties.privateIPAddress]" } } ] @@ -322,6 +393,7 @@ "name": "HTTPRoutingRule", "properties": { "ruleType": "Basic", + "priority": 1000, "httpListener": { "id": "[variables('ref_httpListener')]" }, @@ -338,6 +410,7 @@ "name": "HTTPSRoutingRule", "properties": { "ruleType": "Basic", + "priority": 1001, "httpListener": { "id": "[variables('ref_httpsListener')]" }, @@ -371,6 +444,12 @@ "type": "Microsoft.Network/applicationGateways/probes" } ], + "webApplicationFirewallConfiguration": { + "enabled": true, + "firewallMode": "Prevention", + "ruleSetType": "OWASP", + "ruleSetVersion": "3.0" + }, "enableHttp2": false, "autoscaleConfiguration": { "minCapacity": 2, @@ -379,12 +458,13 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", + "tags": "[parameters('tagsByResource')['${identifier.virtualMachinesExtensions}']]", "name": "[concat(parameters('adminVMName'),'/newuserscript')]", "location": "[parameters('location')]", "dependsOn": [ - "[resourceId('Microsoft.Network/applicationGateways', variables('name_appGateway'))]" + "[resourceId('Microsoft.Network/applicationGateways', parameters('appGatewayName'))]" ], "properties": { "publisher": "Microsoft.Azure.Extensions", @@ -397,13 +477,14 @@ ] }, "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptAGWConfiguration'),' <<< \"', variables('const_adminServerName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('adminVMName'),' ',variables('const_wlsAdminPort'),' ', if(parameters('overrideHostName'), parameters('customDomainName'), reference(variables('ref_appGatewayPublicIP'), '${azure.apiVersion}').dnsSettings.fqdn), ' ',variables('const_wlsHome'),'\"')]" + "commandToExecute": "[concat('sh',' ',variables('name_scriptAGWConfiguration'),' <<< \"', variables('const_adminServerName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('adminVMName'),' ',variables('const_wlsAdminPort'),' ', if(parameters('overrideHostName'), parameters('customDomainName'), reference(variables('ref_appGatewayPublicIP'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn), ' ',variables('const_wlsHome'),'\"')]" } } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "name": "${cluster.appgateway.end}", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" @@ -422,15 +503,15 @@ "outputs": { "appGatewayAlias": { "type": "string", - "value": "[reference(variables('ref_appGatewayPublicIP'), '${azure.apiVersion}').dnsSettings.fqdn]" + "value": "[reference(variables('ref_appGatewayPublicIP'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn]" }, "appGatewayURL": { "type": "string", - "value": "[concat('http://',reference(variables('ref_appGatewayPublicIP'), '${azure.apiVersion}').dnsSettings.fqdn)]" + "value": "[uri(format('http://{0}',reference(variables('ref_appGatewayPublicIP'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn),'')]" }, "appGatewaySecuredURL": { "type": "string", - "value": "[concat('https://',reference(variables('ref_appGatewayPublicIP'), '${azure.apiVersion}').dnsSettings.fqdn)]" + "value": "[uri(format('https://{0}',reference(variables('ref_appGatewayPublicIP'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn),'')]" } } } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/clusterCustomSSLTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/clusterCustomSSLTemplate.json index dce13e2f9..3774a0767 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/clusterCustomSSLTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/clusterCustomSSLTemplate.json @@ -22,6 +22,18 @@ "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." } }, + "_globalResourceNameSuffix":{ + "type": "string", + "metadata": { + "description": "The suffix to be appended to the globally unique resource name" + } + }, + "const_guidTag" :{ + "type": "string", + "metadata": { + "description": "A unique tag for resources." + } + }, "adminPasswordOrKey": { "type": "securestring", "metadata": { @@ -42,6 +54,13 @@ "description": "Admin Server hosting VM name." } }, + "adminVMNamePrefix": { + "defaultValue": "adminVM", + "type": "string", + "metadata": { + "description": "Admin Server hosting VM name prefix." + } + }, "authenticationType": { "defaultValue": "password", "type": "string", @@ -59,10 +78,6 @@ "description": "Unique DNS Name for the Public IP used to access the Virtual Machine." } }, - "guidValue": { - "type": "string", - "defaultValue": "[newGuid()]" - }, "location": { "type": "string", "metadata": { @@ -76,6 +91,12 @@ "description": "Provide managed server prefix name" } }, + "managedVMNamePrefix": { + "type": "string", + "metadata": { + "description": "Provide managed server VM prefix name" + } + }, "numberOfInstances": { "type": "int", "defaultValue": 2, @@ -85,6 +106,12 @@ "description": "Number of VMs to deploy, limit 5 since this sample is using a single storage account" } }, + "nsgName": { + "type": "string", + "metadata": { + "description": "Name of the new Network Security Group" + } + }, "portsToExpose": { "type": "string", "defaultValue": "80,443,7001-9000", @@ -94,18 +121,33 @@ }, "skuUrnVersion": { "type": "string", - "defaultValue": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "defaultValue": "owls-141200-jdk21-ol94;Oracle:weblogic-141200-jdk21-ol94:owls-141200-jdk21-ol94;latest", "allowedValues": [ - "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest", - "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest", - "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest", - "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest", - "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" + "owls-141200-jdk21-ol94;Oracle:weblogic-141200-jdk21-ol94:owls-141200-jdk21-ol94;latest", + "owls-141200-jdk21-ol810;Oracle:weblogic-141200-jdk21-ol810:owls-141200-jdk21-ol810;latest", + "owls-141200-jdk17-ol94;Oracle:weblogic-141200-jdk17-ol94:owls-141200-jdk17-ol94;latest", + "owls-141200-jdk17-ol810;Oracle:weblogic-141200-jdk17-ol810:owls-141200-jdk17-ol810;latest", + "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", + "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest", + "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest", + "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest", + "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest", + "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest", + "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest", + "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest" ], "metadata": { "description": "The Oracle Linux image with Weblogic and Java preinstalled. Semicolon separated string of Sku, URN, and Version" } }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, "usePreviewImage": { "type": "bool", "defaultValue": false, @@ -120,13 +162,75 @@ "description": "Bool value, if it's set to true, a system assigned managed identity will to be created for the VM(s)" } }, - "vmSizeSelect": { + "vmSize": { "type": "string", "defaultValue": "Standard_A3", "metadata": { "description": "Select appropriate VM Size as per requirement" } }, + "virtualNetworkNewOrExisting": { + "type": "string", + "defaultValue": "new", + "allowedValues": [ + "new", + "existing" + ], + "metadata": { + "description": "Specify whether to create a new or existing virtual network for the VM." + } + }, + "virtualNetworkName": { + "type": "string", + "defaultValue": "wls-vnet", + "metadata": { + "description": "Name of the existing or new VNET" + } + }, + "virtualNetworkResourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "Resource group of Virtual network" + } + }, + "addressPrefixes": { + "type": "array", + "defaultValue": [ + "10.0.0.0/28" + ], + "metadata": { + "description": "Address prefix of the VNET." + } + }, + "subnetName": { + "type": "string", + "defaultValue": "wls-subnet", + "metadata": { + "description": "Name of the existing or new Subnet" + } + }, + "subnetPrefix": { + "type": "string", + "defaultValue": "10.0.0.0/29", + "metadata": { + "description": "Address prefix of the subnet" + } + }, + "subnetForAppGateway": { + "type": "string", + "defaultValue": "appgateway-subnet", + "metadata": { + "description": "Name of the existing or new Subnet for Application Gateway" + } + }, + "subnetPrefixForAppGateway": { + "type": "string", + "defaultValue": "10.0.1.0/24", + "metadata": { + "description": "Address prefix of the subnet for Application Gateway" + } + }, "wlsDomainName": { "type": "string", "metadata": { @@ -146,6 +250,13 @@ "description": "Password for your Weblogic domain name" } }, + "enableAppGateway": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "If true, deploy an Azure App Gateway in front of the nodes of the cluster" + } + }, "enableHTTPAdminListenPort":{ "type": "bool", "defaultValue": true, @@ -153,6 +264,20 @@ "description": "Boolean value indicating, if WebLogic Admin Server HTTP Listen Port is enabled or not" } }, + "enableDNSConfiguration": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "Boolean value indicating, if DNS Zone Configuration is enabled or not" + } + }, + "customDNSNameForAdminServer": { + "type": "string", + "defaultValue": "none", + "metadata": { + "description": "Custom DNS Name for WebLogic Admin Server" + } + }, "enableCustomSSL":{ "defaultValue":true, "type": "bool", @@ -160,51 +285,51 @@ "description": "Boolean value indicating, if custom SSL is enabled or not" } }, - "keyVaultCustomIdentityKeyStoreData": { + "sslCustomIdentityKeyStoreData": { "type": "securestring", "metadata": { "description": "Weblogic Custom Identity Keystore Data" } }, - "keyVaultCustomIdentityKeyStorePassPhrase": { + "sslCustomIdentityKeyStorePassPhrase": { "type": "securestring", "metadata": { "description": "Weblogic Custom Identity Keystore Passphrase" } }, - "keyVaultCustomIdentityKeyStoreType": { + "sslCustomIdentityKeyStoreType": { "type": "string", "metadata": { "description": "Weblogic Custom Identity Keystore Type" }, "defaultValue": "JKS" }, - "keyVaultCustomTrustKeyStoreData": { + "sslCustomTrustKeyStoreData": { "type": "securestring", "metadata": { "description": "Weblogic Custom Trust Store Data" } }, - "keyVaultCustomTrustKeyStorePassPhrase": { + "sslCustomTrustKeyStorePassPhrase": { "type": "securestring", "metadata": { "description": "Weblogic Custom Trust Store Passphrase" } }, - "keyVaultCustomTrustKeyStoreType": { + "sslCustomTrustKeyStoreType": { "type": "string", "metadata": { "description": "Weblogic Custom Trust Store Type" }, "defaultValue": "JKS" }, - "keyVaultPrivateKeyAlias": { + "sslPrivateKeyAlias": { "type": "string", "metadata": { "description": "Weblogic Server Private Key Alias" } }, - "keyVaultPrivateKeyPassPhrase": { + "sslPrivateKeyPassPhrase": { "type": "securestring", "metadata": { "description": "Weblogic Server Private Key Pass Phrase" @@ -212,8 +337,8 @@ } }, "variables": { - "const_addressPrefix": "10.0.0.0/16", - "const_appGatewaySubnetPrefix": "10.0.1.0/24", + "const_addressPrefix": "[parameters('addressPrefixes')]", + "const_appGatewaySubnetPrefix": "[parameters('subnetPrefixForAppGateway')]", "const_hyphen": "-", "const_imageOffer": "[concat('weblogic',variables('const_hyphen'), split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[1],variables('const_hyphen'),split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[2],variables('const_hyphen'),split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[3],if(parameters('usePreviewImage'),'-preview',''))]", "const_imagePublisher": "oracle", @@ -228,37 +353,78 @@ ] } }, - "const_managedVMPrefix": "[concat(parameters('managedServerPrefix'),'VM')]", + "const_managedVMPrefix": "[concat(parameters('managedVMNamePrefix'),'VM')]", "const_mountPointPath": "[concat('/mnt/', variables('name_share'))]", "const_publicIPAddressType": "Dynamic", "const_requiredPortrange": ",65200-65535,5556", "const_storageAccountType": "Standard_LRS", - "const_subnetPrefix": "10.0.0.0/24", - "const_vmSize": "[parameters('vmSizeSelect')]", + "const_subnetPrefix": "[parameters('subnetPrefix')]", + "const_vmSize": "[parameters('vmSize')]", "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", - "name_appGatewaySubnet": "appGatewaySubnet", - "name_availabilitySet": "WLSCluster-AvailabilitySet", + "name_appGatewaySubnet": "[parameters('subnetForAppGateway')]", + "name_availabilitySet": "[concat('wlscluster-availabilityset-', parameters('_globalResourceNameSuffix'))]", "name_linuxImageOfferSKU": "[first(split(parameters('skuUrnVersion'), ';'))]", "name_linuxImageVersion": "[last(split(parameters('skuUrnVersion'),';'))]", - "name_networkSecurityGroup": "[concat(parameters('dnsLabelPrefix'), '-nsg')]", "name_nic": "_NIC", "name_publicIPAddress": "_PublicIP", - "name_outputAdminHost": "[concat(parameters('adminVMName'),variables('name_publicIPAddress'))]", + "name_nic_with_pub_ip": "[concat(variables('name_nic'), '_with_pub_ip')]", + "name_nic_without_pub_ip": "[concat(variables('name_nic'), '_without_pub_ip')]", + "name_outputAdminHost_with_pub_ip": "[concat(parameters('adminVMName'),variables('name_publicIPAddress'))]", + "name_outputAdminHost_without_pub_ip": "[concat(parameters('adminVMName'),variables('name_nic_without_pub_ip'))]", + "name_privateSaEndpoint": "[concat('saep', parameters('_globalResourceNameSuffix'))]", "name_scriptFile": "setupClusterDomain.sh", "name_share": "wlsshare", - "name_storageAccount": "[concat(take(replace(parameters('guidValue'),'-',''),6),'olvm')]", - "name_subnet": "Subnet", - "name_virtualNetwork": "[concat(parameters('wlsDomainName'),'_VNET')]", + "name_storageAccount": "[concat('olvmstg', parameters('_globalResourceNameSuffix'))]", + "name_subnet": "[parameters('subnetName')]", + "name_virtualNetwork": "[parameters('virtualNetworkName')]", "ref_fileService": "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('name_storageAccount'), 'default')]", - "ref_networkSecurityGroup": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('name_networkSecurityGroup'))]", + "ref_networkSecurityGroup": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('nsgName'))]", "ref_storage": "[resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount'))]", - "ref_subnet": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]" - + "ref_subnet": "[resourceId(parameters('virtualNetworkResourceGroupName'),'Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]", + "name_customHostnameGeneratorscriptFile": "generateCustomHostNameVerifier.sh", + "name_customHostnameVerifierJavaFile": "src/main/java/WebLogicCustomHostNameVerifier.java", + "name_customHostnameValuesTemplate": "src/main/java/HostNameValuesTemplate.txt", + "name_customHostnameVerifierTest" : "src/test/java/WebLogicCustomHostNameVerifierTest.java", + "property_subnet_with_app_gateway": [ + { + "name": "[variables('name_subnet')]", + "properties": { + "addressPrefix": "[variables('const_subnetPrefix')]", + "networkSecurityGroup": { + "id": "[variables('ref_networkSecurityGroup')]" + } + } + }, + { + // PENDING(edburns): Assume it is acceptable to create a subnet for the App Gateway, even if the user + // has not requested an App Gateway. In support of this assumption we can note: the user may want an App + // Gateway after deployment. + "name": "[variables('name_appGatewaySubnet')]", + "properties": { + "addressPrefix": "[variables('const_appGatewaySubnetPrefix')]", + "networkSecurityGroup": { + "id": "[variables('ref_networkSecurityGroup')]" + } + } + } + ], + "property_subnet_without_app_gateway": [ + { + "name": "[variables('name_subnet')]", + "properties": { + "addressPrefix": "[variables('const_subnetPrefix')]", + "networkSecurityGroup": { + "id": "[variables('ref_networkSecurityGroup')]" + } + } + } + ] }, "resources": [ { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "name": "${cluster.cluster.start}", "properties": { "mode": "Incremental", @@ -271,9 +437,26 @@ } }, { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${cluster.ssl.start}", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "apiVersion": "${azure.apiVersionForNetworkSecurityGroups}", "type": "Microsoft.Network/networkSecurityGroups", - "apiVersion": "${azure.apiVersion}", - "name": "[variables('name_networkSecurityGroup')]", + "tags": "[parameters('tagsByResource')['${identifier.networkSecurityGroups}']]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", + "name": "[parameters('nsgName')]", "location": "[parameters('location')]", "properties": { "securityRules": [ @@ -336,23 +519,51 @@ }, { "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "${azure.apiVersion2}", + "apiVersion": "${azure.apiVersionForStorage}", + "tags": "[parameters('tagsByResource')['${identifier.storageAccounts}']]", "name": "[variables('name_storageAccount')]", "location": "[parameters('location')]", "sku": { "name": "[variables('const_storageAccountType')]" }, - "kind": "Storage", + "kind": "StorageV2", "properties": { "supportsHttpsTrafficOnly": false }, "dependsOn": [ - "[variables('name_networkSecurityGroup')]" + "[parameters('nsgName')]" + ] + }, + { + "apiVersion": "${azure.apiVersionForPrivateEndpoint}", + "name": "[variables('name_privateSaEndpoint')]", + "type": "Microsoft.Network/privateEndpoints", + "tags": "[parameters('tagsByResource')['${identifier.privateEndpoints}']]", + "location": "[parameters('location')]", + "properties": { + "privateLinkServiceConnections": [ + { + "name": "[variables('name_privateSaEndpoint')]", + "properties": { + "privateLinkServiceId": "[resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount'))]", + "groupIds": [ + "file" + ] + } + } + ], + "subnet": { + "id": "[variables('ref_subnet')]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount'))]", + "[variables('name_virtualNetwork')]" ] }, { "type": "Microsoft.Storage/storageAccounts/fileServices", - "apiVersion": "${azure.apiVersion2}", + "apiVersion": "${azure.apiVersionForStorageFileService}", "name": "[concat(variables('name_storageAccount'), '/default')]", "dependsOn": [ "[variables('ref_storage')]" @@ -364,7 +575,7 @@ }, { "type": "Microsoft.Storage/storageAccounts/fileServices/shares", - "apiVersion": "${azure.apiVersion2}", + "apiVersion": "${azure.apiVersionForStorageFileService}", "name": "[concat(variables('name_storageAccount'), '/default/', variables('name_share'))]", "dependsOn": [ "[variables('ref_fileService')]", @@ -375,8 +586,9 @@ } }, { + "apiVersion": "${azure.apiVersionForPublicIPAddresses}", "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "${azure.apiVersion}", + "tags": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'),parameters('tagsByResource')['${identifier.publicIPAddresses}'],if(empty(parameters('tagsByResource')['${identifier.publicIPAddresses}']),createObject(parameters('const_guidTag'),''),union(parameters('tagsByResource')['${identifier.publicIPAddresses}'],createObject(parameters('const_guidTag'),''))))]", "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_publicIPAddress')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_publicIPAddress')))]", "location": "[parameters('location')]", "copy": { @@ -386,7 +598,7 @@ "properties": { "publicIPAllocationMethod": "[variables('const_publicIPAddressType')]", "dnsSettings": { - "domainNameLabel": "[concat(toLower(parameters('dnsLabelPrefix')),copyindex(),'-',take(replace(parameters('guidValue'),'-',''),10),'-',toLower(parameters('wlsDomainName')))]" + "domainNameLabel": "[take(concat(toLower(parameters('dnsLabelPrefix')), copyindex(),'-', parameters('_globalResourceNameSuffix'),'-',toLower(parameters('wlsDomainName'))), 50)]" } }, "dependsOn": [ @@ -394,8 +606,10 @@ ] }, { + "apiVersion": "${azure.apiVersionForVirtualNetworks}", "type": "Microsoft.Network/virtualNetworks", - "apiVersion": "${azure.apiVersion}", + "tags": "[parameters('tagsByResource')['${identifier.virtualNetworks}']]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", "name": "[variables('name_virtualNetwork')]", "location": "[parameters('location')]", "dependsOn": [ @@ -403,42 +617,55 @@ ], "properties": { "addressSpace": { - "addressPrefixes": [ - "[variables('const_addressPrefix')]" - ] + "addressPrefixes": "[variables('const_addressPrefix')]" }, - "subnets": [ - { - "name": "[variables('name_subnet')]", - "properties": { - "addressPrefix": "[variables('const_subnetPrefix')]", - "networkSecurityGroup": { - "id": "[variables('ref_networkSecurityGroup')]" - } - } - }, + "subnets": "[if(parameters('enableAppGateway'), variables('property_subnet_with_app_gateway'), variables('property_subnet_without_app_gateway'))]" + + } + }, + { + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", + "type": "Microsoft.Network/networkInterfaces", + "tags": "[parameters('tagsByResource')['${identifier.networkInterfaces}']]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", + "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_nic_with_pub_ip')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic_with_pub_ip')))]", "location": "[parameters('location')]", + "copy": { + "name": "nicLoop_public_ip", + "count": "[parameters('numberOfInstances')]" + }, + "dependsOn": [ + "[variables('name_virtualNetwork')]", + "publicIPLoop" + ], + "properties": { + "ipConfigurations": [ { - // PENDING(edburns): Assume it is acceptable to create a subnet for the App Gateway, even if the user - // has not requested an App Gateway. In support of this assumption we can note: the user may want an App - // Gateway after deployment. - "name": "[variables('name_appGatewaySubnet')]", + "name": "ipconfig1", "properties": { - "addressPrefix": "[variables('const_appGatewaySubnetPrefix')]", - "networkSecurityGroup": { - "id": "[variables('ref_networkSecurityGroup')]" + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses',if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_publicIPAddress')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_publicIPAddress'))))]" + }, + "subnet": { + "id": "[variables('ref_subnet')]" } } } - ] + ], + "dnsSettings": { + "internalDnsNameLabel": "[if(equals(copyIndex(),0),parameters('adminVMName'),concat(variables('const_managedVMPrefix'), copyIndex()))]" + } } }, { "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "${azure.apiVersion}", - "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_nic')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic')))]", + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", + "tags": "[parameters('tagsByResource')['${identifier.networkInterfaces}']]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'existing')]", + "name": "[if(equals(copyIndex(),0),variables('name_outputAdminHost_without_pub_ip'),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic_without_pub_ip')))]", "location": "[parameters('location')]", "copy": { - "name": "nicLoop", + "name": "nicLoop_private_ip", "count": "[parameters('numberOfInstances')]" }, "dependsOn": [ @@ -452,22 +679,20 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses',if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_publicIPAddress')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_publicIPAddress'))))]" + "id": "[resourceId('${identifier.publicIPAddresses}',if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_publicIPAddress')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_publicIPAddress'))))]" }, "subnet": { "id": "[variables('ref_subnet')]" } } } - ], - "dnsSettings": { - "internalDnsNameLabel": "[if(equals(copyIndex(),0),parameters('adminVMName'),concat(variables('const_managedVMPrefix'), copyIndex()))]" - } + ] } }, { "type": "Microsoft.Compute/availabilitySets", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForAvailabilitySets}", + "tags": "[parameters('tagsByResource')['${identifier.availabilitySets}']]", "location": "[parameters('location')]", "name": "[variables('name_availabilitySet')]", "properties": { @@ -482,8 +707,9 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "${azure.apiVersion}", + "tags": "[parameters('tagsByResource')['${identifier.virtualMachines}']]", "name": "[if(equals(copyIndex(),0),parameters('adminVMName'),concat(variables('const_managedVMPrefix'), copyIndex()))]", "location": "[parameters('location')]", "copy": { @@ -491,8 +717,10 @@ "count": "[parameters('numberOfInstances')]" }, "dependsOn": [ - "nicLoop", - "[resourceId('Microsoft.Compute/availabilitySets/', variables('name_availabilitySet'))]" + "nicLoop_public_ip", + "nicLoop_private_ip", + "[resourceId('Microsoft.Compute/availabilitySets/', variables('name_availabilitySet'))]", + "[variables('name_privateSaEndpoint')]" ], "identity": "[if(parameters('useSystemAssignedManagedIdentity'), json('{\"type\":\"SystemAssigned\"}'), null())]", "properties": { @@ -520,29 +748,19 @@ "managedDisk": { "storageAccountType": "Standard_LRS" } - }, - "dataDisks": [ - { - "lun": 0, - "createOption": "FromImage", - "diskSizeGB": 900, - "managedDisk": { - "storageAccountType": "Standard_LRS" - } - } - ] + } }, "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces',if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_nic')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic'))))]" + "id": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), resourceId('Microsoft.Network/networkInterfaces',if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_nic_with_pub_ip')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic_with_pub_ip')))), resourceId('Microsoft.Network/networkInterfaces',if(equals(copyIndex(),0),variables('name_outputAdminHost_without_pub_ip'),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic_without_pub_ip')))))]" } ] }, "diagnosticsProfile": { "bootDiagnostics": { "enabled": true, - "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount')), '${azure.apiVersion2}').primaryEndpoints.blob]" + "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount')), '${azure.apiVersionForStorage}').primaryEndpoints.blob]" } } }, @@ -553,8 +771,9 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", + "tags": "[parameters('tagsByResource')['${identifier.virtualMachinesExtensions}']]", "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),'/newuserscript'),concat(variables('const_managedVMPrefix'), copyIndex(),'/newuserscript'))]", "location": "[parameters('location')]", "copy": { @@ -572,17 +791,40 @@ "autoUpgradeMinorVersion": true, "settings": { "fileUris": [ - "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../scripts/', variables('name_scriptFile'), parameters('_artifactsLocationSasToken')))]" + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../scripts/', variables('name_scriptFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameGeneratorscriptFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierJavaFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameValuesTemplate'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierTest'), parameters('_artifactsLocationSasToken')))]" ] }, "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'),' <<< \"',parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',if(equals(copyIndex(),0),'admin',concat(parameters('managedServerPrefix'), copyIndex())),' ',parameters('adminVMName'),' ',variables('const_wlsHome'),' ',variables('name_storageAccount'),' ',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount')), '${azure.apiVersion2}').keys[0].value,' ',variables('const_mountPointPath'),' ',string(parameters('enableHTTPAdminListenPort')),' ',string(parameters('enableCustomSSL')),' ',base64(parameters('keyVaultCustomIdentityKeyStoreData')),' ',base64(parameters('keyVaultCustomIdentityKeyStorePassPhrase')),' ',base64(parameters('keyVaultCustomIdentityKeyStoreType')),' ',base64(parameters('keyVaultCustomTrustKeyStoreData')),' ',base64(parameters('keyVaultCustomTrustKeyStorePassPhrase')),' ',base64(parameters('keyVaultCustomTrustKeyStoreType')),' ',base64(parameters('keyVaultPrivateKeyAlias')),' ',base64(parameters('keyVaultPrivateKeyPassPhrase')),'\"')]" + "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'),' <<< \"',parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',if(equals(copyIndex(),0),'admin',concat(parameters('managedServerPrefix'), copyIndex())),' ',parameters('adminVMName'),' ',parameters('adminVMNamePrefix'),' ',parameters('_globalResourceNameSuffix'),' ',parameters('numberOfInstances'),' ',variables('const_managedVMPrefix'),' ', parameters('managedServerPrefix'),' ',variables('const_wlsHome'),' ',variables('name_storageAccount'),' ',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount')), '${azure.apiVersionForStorage}').keys[0].value,' ',variables('const_mountPointPath'),' ',string(parameters('enableHTTPAdminListenPort')),' ',string(parameters('enableCustomSSL')),' ',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), if(parameters('enableDNSConfiguration'),parameters('customDNSNameForAdminServer'),reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn), reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),' ',parameters('dnsLabelPrefix'),' ',parameters('location'),' ', parameters('virtualNetworkNewOrExisting'),' ',reference(resourceId('Microsoft.Network/privateEndpoints/', variables('name_privateSaEndpoint')), '${azure.apiVersionForPrivateEndpoint}').customDnsConfigs[0].ipAddresses[0],' ',base64(parameters('sslCustomIdentityKeyStoreData')),' ',base64(parameters('sslCustomIdentityKeyStorePassPhrase')),' ',base64(parameters('sslCustomIdentityKeyStoreType')),' ',base64(parameters('sslCustomTrustKeyStoreData')),' ',base64(parameters('sslCustomTrustKeyStorePassPhrase')),' ',base64(parameters('sslCustomTrustKeyStoreType')),' ',base64(parameters('sslPrivateKeyAlias')),' ',base64(parameters('sslPrivateKeyPassPhrase')),'\"')]" + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${cluster.ssl.end}", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] } } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "name": "${cluster.cluster.end}", "dependsOn": [ "virtualMachineExtensionLoop" @@ -599,10 +841,71 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-122130-jdk8-ol74}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141200-jdk21-ol94}", + + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk21-ol94'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141200-jdk21-ol810}", + + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk21-ol810'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141200-jdk17-ol94}", + + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk17-ol94'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141200-jdk17-ol810}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122130-jdk8-ol74'), bool('true'), bool('false'))]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk17-ol810'), bool('true'), bool('false'))]", "dependsOn": [ "virtualMachineExtensionLoop" ], @@ -618,9 +921,11 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-122130-jdk8-ol73}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'from.owls-122130-jdk8-ol73'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141100-jdk11-ol91}", + + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol91'), bool('true'), bool('false'))]", "dependsOn": [ "virtualMachineExtensionLoop" ], @@ -636,10 +941,11 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-122140-jdk8-ol76}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141100-jdk11-ol87}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'from.owls-122140-jdk8-ol76'), bool('true'), bool('false'))]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol87'), bool('true'), bool('false'))]", "dependsOn": [ "virtualMachineExtensionLoop" ], @@ -655,9 +961,11 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-141100-jdk8-ol76}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol76'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141100-jdk8-ol91}", + + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol91'), bool('true'), bool('false'))]", "dependsOn": [ "virtualMachineExtensionLoop" ], @@ -673,9 +981,108 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-141100-jdk11-ol76}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol76'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141100-jdk8-ol87}", + + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol87'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-122140-jdk8-ol91}", + + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-ol91'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-122140-jdk8-ol87}", + + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-ol87'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141100-jdk11-rhel87}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-rhel87'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141100-jdk8-rhel87}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-rhel87'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-122140-jdk8-rhel87}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-rhel87'), bool('true'), bool('false'))]", "dependsOn": [ "virtualMachineExtensionLoop" ], @@ -693,7 +1100,7 @@ "outputs": { "_adminPublicIPId": { "type": "string", - "value": "[resourceId('Microsoft.Network/publicIPAddresses',concat(parameters('adminVMName'),variables('name_publicIPAddress')))]" + "value": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'),resourceId('Microsoft.Network/publicIPAddresses',concat(parameters('adminVMName'),variables('name_publicIPAddress'))),'')]" }, "artifactsLocationPassedIn": { "type": "string", @@ -701,16 +1108,24 @@ }, "adminHostName": { "type": "string", - "value": "[reference(variables('name_outputAdminHost'), '${azure.apiVersion}').dnsSettings.fqdn]" + "value": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn, reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress)]" }, "adminConsole": { "type": "string", - "value": "[concat('http://',reference(variables('name_outputAdminHost'), '${azure.apiVersion}').dnsSettings.fqdn,':7001/console')]" + "value": "[uri(concat('http://',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'),reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn,reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7001/console/'),'')]" }, "adminSecuredConsole": { "type": "string", - "value": "[concat('https://',reference(variables('name_outputAdminHost'), '${azure.apiVersion}').dnsSettings.fqdn,':7002/console')]" + "value": "[uri(concat('https://',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'),reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn,reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7002/console/'),'')]" + }, + "adminRemoteConsoleURL": { + "type": "string", + "value": "[uri(concat('http://',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'),reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn,reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7001'),'')]" }, + "adminRemoteConsoleSecuredURL": { + "type": "string", + "value": "[uri(concat('https://',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'),reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn,reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7002'),'')]" + }, "wlsDomainLocation": { "type": "string", "value": "[concat('/u01/domains/', parameters('wlsDomainName'))]" diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/clusterTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/clusterTemplate.json index 514d66b5f..a4d6f0ea8 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/clusterTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/clusterTemplate.json @@ -22,6 +22,18 @@ "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." } }, + "_globalResourceNameSuffix":{ + "type": "string", + "metadata": { + "description": "The suffix to be appended to the globally unique resource name" + } + }, + "const_guidTag" :{ + "type": "string", + "metadata": { + "description": "A unique tag for resources." + } + }, "adminPasswordOrKey": { "type": "securestring", "metadata": { @@ -42,6 +54,13 @@ "description": "Admin Server hosting VM name." } }, + "adminVMNamePrefix": { + "defaultValue": "adminVM", + "type": "string", + "metadata": { + "description": "Admin Server hosting VM name prefix." + } + }, "authenticationType": { "defaultValue": "password", "type": "string", @@ -59,10 +78,6 @@ "description": "Unique DNS Name for the Public IP used to access the Virtual Machine." } }, - "guidValue": { - "type": "string", - "defaultValue": "[newGuid()]" - }, "location": { "type": "string", "metadata": { @@ -76,6 +91,12 @@ "description": "Provide managed server prefix name" } }, + "managedVMNamePrefix": { + "type": "string", + "metadata": { + "description": "Provide managed server VM name prefix" + } + }, "numberOfInstances": { "type": "int", "defaultValue": 2, @@ -94,18 +115,33 @@ }, "skuUrnVersion": { "type": "string", - "defaultValue": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "defaultValue": "owls-141200-jdk21-ol94;Oracle:weblogic-141200-jdk21-ol94:owls-141200-jdk21-ol94;latest", "allowedValues": [ - "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest", - "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest", - "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest", - "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest", - "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" + "owls-141200-jdk21-ol94;Oracle:weblogic-141200-jdk21-ol94:owls-141200-jdk21-ol94;latest", + "owls-141200-jdk21-ol810;Oracle:weblogic-141200-jdk21-ol810:owls-141200-jdk21-ol810;latest", + "owls-141200-jdk17-ol94;Oracle:weblogic-141200-jdk17-ol94:owls-141200-jdk17-ol94;latest", + "owls-141200-jdk17-ol810;Oracle:weblogic-141200-jdk17-ol810:owls-141200-jdk17-ol810;latest", + "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", + "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest", + "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest", + "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest", + "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest", + "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest", + "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest", + "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest" ], "metadata": { "description": "The Oracle Linux image with Weblogic and Java preinstalled. Semicolon separated string of Sku, URN, and Version" } }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, "usePreviewImage": { "type": "bool", "defaultValue": false, @@ -120,13 +156,81 @@ "description": "Bool value, if it's set to true, a system assigned managed identity will to be created for the VM(s)" } }, - "vmSizeSelect": { + "vmSize": { "type": "string", "defaultValue": "Standard_A3", "metadata": { "description": "Select appropriate VM Size as per requirement" } }, + "virtualNetworkNewOrExisting": { + "type": "string", + "defaultValue": "new", + "allowedValues": [ + "new", + "existing" + ], + "metadata": { + "description": "Specify whether to create a new or existing virtual network for the VM." + } + }, + "virtualNetworkName": { + "type": "string", + "defaultValue": "wls-vnet", + "metadata": { + "description": "Name of the existing or new VNET" + } + }, + "virtualNetworkResourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "Resource group of Virtual network" + } + }, + "addressPrefixes": { + "type": "array", + "defaultValue": [ + "10.0.0.0/28" + ], + "metadata": { + "description": "Address prefix of the VNET." + } + }, + "nsgName": { + "type": "string", + "metadata": { + "description": "Name of the new Network Security Group" + } + }, + "subnetName": { + "type": "string", + "defaultValue": "wls-subnet", + "metadata": { + "description": "Name of the existing or new Subnet" + } + }, + "subnetPrefix": { + "type": "string", + "defaultValue": "10.0.0.0/29", + "metadata": { + "description": "Address prefix of the subnet" + } + }, + "subnetForAppGateway": { + "type": "string", + "defaultValue": "appgateway-subnet", + "metadata": { + "description": "Name of the existing or new Subnet for Application Gateway" + } + }, + "subnetPrefixForAppGateway": { + "type": "string", + "defaultValue": "10.0.1.0/24", + "metadata": { + "description": "Address prefix of the subnet for Application Gateway" + } + }, "wlsDomainName": { "type": "string", "metadata": { @@ -152,11 +256,32 @@ "metadata": { "description": "Boolean value indicating, if WebLogic Admin Server HTTP Listen Port is enabled or not" } + }, + "enableDNSConfiguration": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "Boolean value indicating, if DNS Zone Configuration is enabled or not" + } + }, + "enableAppGateway": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "If true, deploy an Azure App Gateway in front of the nodes of the cluster" + } + }, + "customDNSNameForAdminServer": { + "type": "string", + "defaultValue": "none", + "metadata": { + "description": "Custom DNS Name for WebLogic Admin Server" + } } }, "variables": { - "const_addressPrefix": "10.0.0.0/16", - "const_appGatewaySubnetPrefix": "10.0.1.0/24", + "const_addressPrefix": "[parameters('addressPrefixes')]", + "const_appGatewaySubnetPrefix": "[parameters('subnetPrefixForAppGateway')]", "const_hyphen": "-", "const_imageOffer": "[concat('weblogic',variables('const_hyphen'), split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[1],variables('const_hyphen'),split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[2],variables('const_hyphen'),split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[3],if(parameters('usePreviewImage'),'-preview',''))]", "const_imagePublisher": "oracle", @@ -171,37 +296,79 @@ ] } }, - "const_managedVMPrefix": "[concat(parameters('managedServerPrefix'),'VM')]", + "const_managedVMPrefix": "[concat(parameters('managedVMNamePrefix'), 'VM')]", "const_mountPointPath": "[concat('/mnt/', variables('name_share'))]", "const_publicIPAddressType": "Dynamic", "const_requiredPortrange": ",65200-65535,5556", "const_storageAccountType": "Standard_LRS", - "const_subnetPrefix": "10.0.0.0/24", - "const_vmSize": "[parameters('vmSizeSelect')]", + "const_subnetPrefix": "[parameters('subnetPrefix')]", + "const_vmSize": "[parameters('vmSize')]", "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", - "name_appGatewaySubnet": "appGatewaySubnet", - "name_availabilitySet": "WLSCluster-AvailabilitySet", + "name_appGatewaySubnet": "[parameters('subnetForAppGateway')]", + "name_availabilitySet": "[concat('wlscluster-availabilityset-', parameters('_globalResourceNameSuffix'))]", "name_linuxImageOfferSKU": "[first(split(parameters('skuUrnVersion'), ';'))]", "name_linuxImageVersion": "[last(split(parameters('skuUrnVersion'),';'))]", - "name_networkSecurityGroup": "[concat(parameters('dnsLabelPrefix'), '-nsg')]", "name_nic": "_NIC", + "name_nic_with_pub_ip": "[concat(variables('name_nic'), '_with_pub_ip')]", + "name_nic_without_pub_ip": "[concat(variables('name_nic'), '_without_pub_ip')]", "name_publicIPAddress": "_PublicIP", - "name_outputAdminHost": "[concat(parameters('adminVMName'),variables('name_publicIPAddress'))]", + "name_outputAdminHost_with_pub_ip": "[concat(parameters('adminVMName'),variables('name_publicIPAddress'))]", + "name_outputAdminHost_without_pub_ip": "[concat(parameters('adminVMName'),variables('name_nic_without_pub_ip'))]", + "name_privateSaEndpoint": "[concat('saep', parameters('_globalResourceNameSuffix'))]", "name_scriptFile": "setupClusterDomain.sh", "name_share": "wlsshare", - "name_storageAccount": "[concat(take(replace(parameters('guidValue'),'-',''),6),'olvm')]", - "name_subnet": "Subnet", - "name_virtualNetwork": "[concat(parameters('wlsDomainName'),'_VNET')]", + "name_storageAccount": "[concat('olvmstg', parameters('_globalResourceNameSuffix'))]", + "name_subnet": "[parameters('subnetName')]", + "name_virtualNetwork": "[parameters('virtualNetworkName')]", "ref_fileService": "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('name_storageAccount'), 'default')]", - "ref_networkSecurityGroup": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('name_networkSecurityGroup'))]", + "ref_networkSecurityGroup": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('nsgName'))]", "ref_storage": "[resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount'))]", - "ref_subnet": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]" + "ref_subnet": "[resourceId(parameters('virtualNetworkResourceGroupName'),'Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]", + "name_customHostnameGeneratorscriptFile": "generateCustomHostNameVerifier.sh", + "name_customHostnameVerifierJavaFile": "src/main/java/WebLogicCustomHostNameVerifier.java", + "name_customHostnameValuesTemplate": "src/main/java/HostNameValuesTemplate.txt", + "name_customHostnameVerifierTest" : "src/test/java/WebLogicCustomHostNameVerifierTest.java", + "property_subnet_with_app_gateway": [ + { + "name": "[variables('name_subnet')]", + "properties": { + "addressPrefix": "[variables('const_subnetPrefix')]", + "networkSecurityGroup": { + "id": "[variables('ref_networkSecurityGroup')]" + } + } + }, + { + // PENDING(edburns): Assume it is acceptable to create a subnet for the App Gateway, even if the user + // has not requested an App Gateway. In support of this assumption we can note: the user may want an App + // Gateway after deployment. + "name": "[variables('name_appGatewaySubnet')]", + "properties": { + "addressPrefix": "[variables('const_appGatewaySubnetPrefix')]", + "networkSecurityGroup": { + "id": "[variables('ref_networkSecurityGroup')]" + } + } + } + ], + "property_subnet_without_app_gateway": [ + { + "name": "[variables('name_subnet')]", + "properties": { + "addressPrefix": "[variables('const_subnetPrefix')]", + "networkSecurityGroup": { + "id": "[variables('ref_networkSecurityGroup')]" + } + } + } + ] }, "resources": [ { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "name": "${cluster.cluster.start}", "properties": { "mode": "Incremental", @@ -214,9 +381,11 @@ } }, { + "apiVersion": "${azure.apiVersionForNetworkSecurityGroups}", "type": "Microsoft.Network/networkSecurityGroups", - "apiVersion": "${azure.apiVersion}", - "name": "[variables('name_networkSecurityGroup')]", + "tags": "[parameters('tagsByResource')['${identifier.networkSecurityGroups}']]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", + "name": "[parameters('nsgName')]", "location": "[parameters('location')]", "properties": { "securityRules": [ @@ -279,23 +448,51 @@ }, { "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "${azure.apiVersion2}", + "apiVersion": "${azure.apiVersionForStorage}", "name": "[variables('name_storageAccount')]", + "tags": "[parameters('tagsByResource')['${identifier.storageAccounts}']]", "location": "[parameters('location')]", "sku": { "name": "[variables('const_storageAccountType')]" }, - "kind": "Storage", + "kind": "StorageV2", "properties": { "supportsHttpsTrafficOnly": false }, "dependsOn": [ - "[variables('name_networkSecurityGroup')]" + "[parameters('nsgName')]" + ] + }, + { + "apiVersion": "${azure.apiVersionForPrivateEndpoint}", + "name": "[variables('name_privateSaEndpoint')]", + "type": "Microsoft.Network/privateEndpoints", + "tags": "[parameters('tagsByResource')['${identifier.privateEndpoints}']]", + "location": "[parameters('location')]", + "properties": { + "privateLinkServiceConnections": [ + { + "name": "[variables('name_privateSaEndpoint')]", + "properties": { + "privateLinkServiceId": "[resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount'))]", + "groupIds": [ + "file" + ] + } + } + ], + "subnet": { + "id": "[variables('ref_subnet')]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount'))]", + "[variables('name_virtualNetwork')]" ] }, { "type": "Microsoft.Storage/storageAccounts/fileServices", - "apiVersion": "${azure.apiVersion2}", + "apiVersion": "${azure.apiVersionForStorageFileService}", "name": "[concat(variables('name_storageAccount'), '/default')]", "dependsOn": [ "[variables('ref_storage')]" @@ -307,7 +504,7 @@ }, { "type": "Microsoft.Storage/storageAccounts/fileServices/shares", - "apiVersion": "${azure.apiVersion2}", + "apiVersion": "${azure.apiVersionForStorageFileService}", "name": "[concat(variables('name_storageAccount'), '/default/', variables('name_share'))]", "dependsOn": [ "[variables('ref_fileService')]", @@ -318,8 +515,9 @@ } }, { + "apiVersion": "${azure.apiVersionForPublicIPAddresses}", "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "${azure.apiVersion}", + "tags": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'),parameters('tagsByResource')['${identifier.publicIPAddresses}'],if(empty(parameters('tagsByResource')['${identifier.publicIPAddresses}']),createObject(parameters('const_guidTag'),''),union(parameters('tagsByResource')['${identifier.publicIPAddresses}'],createObject(parameters('const_guidTag'),''))))]", "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_publicIPAddress')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_publicIPAddress')))]", "location": "[parameters('location')]", "copy": { @@ -329,7 +527,7 @@ "properties": { "publicIPAllocationMethod": "[variables('const_publicIPAddressType')]", "dnsSettings": { - "domainNameLabel": "[concat(toLower(parameters('dnsLabelPrefix')),copyindex(),'-',take(replace(parameters('guidValue'),'-',''),10),'-',toLower(parameters('wlsDomainName')))]" + "domainNameLabel": "[take(concat(toLower(parameters('dnsLabelPrefix')), copyindex(),'-', parameters('_globalResourceNameSuffix'),'-',toLower(parameters('wlsDomainName'))), 50)]" } }, "dependsOn": [ @@ -337,8 +535,10 @@ ] }, { + "apiVersion": "${azure.apiVersionForVirtualNetworks}", "type": "Microsoft.Network/virtualNetworks", - "apiVersion": "${azure.apiVersion}", + "tags": "[parameters('tagsByResource')['${identifier.virtualNetworks}']]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", "name": "[variables('name_virtualNetwork')]", "location": "[parameters('location')]", "dependsOn": [ @@ -346,42 +546,54 @@ ], "properties": { "addressSpace": { - "addressPrefixes": [ - "[variables('const_addressPrefix')]" - ] + "addressPrefixes": "[variables('const_addressPrefix')]" }, - "subnets": [ - { - "name": "[variables('name_subnet')]", - "properties": { - "addressPrefix": "[variables('const_subnetPrefix')]", - "networkSecurityGroup": { - "id": "[variables('ref_networkSecurityGroup')]" - } - } - }, + "subnets": "[if(parameters('enableAppGateway'), variables('property_subnet_with_app_gateway'), variables('property_subnet_without_app_gateway'))]" + } + }, + { + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", + "type": "Microsoft.Network/networkInterfaces", + "tags": "[parameters('tagsByResource')['${identifier.networkInterfaces}']]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", + "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_nic_with_pub_ip')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic_with_pub_ip')))]", "location": "[parameters('location')]", + "copy": { + "name": "nicLoop_public_ip", + "count": "[parameters('numberOfInstances')]" + }, + "dependsOn": [ + "[variables('name_virtualNetwork')]", + "publicIPLoop" + ], + "properties": { + "ipConfigurations": [ { - // PENDING(edburns): Assume it is acceptable to create a subnet for the App Gateway, even if the user - // has not requested an App Gateway. In support of this assumption we can note: the user may want an App - // Gateway after deployment. - "name": "[variables('name_appGatewaySubnet')]", + "name": "ipconfig1", "properties": { - "addressPrefix": "[variables('const_appGatewaySubnetPrefix')]", - "networkSecurityGroup": { - "id": "[variables('ref_networkSecurityGroup')]" + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses',if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_publicIPAddress')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_publicIPAddress'))))]" + }, + "subnet": { + "id": "[variables('ref_subnet')]" } } } - ] + ], + "dnsSettings": { + "internalDnsNameLabel": "[if(equals(copyIndex(),0),parameters('adminVMName'),concat(variables('const_managedVMPrefix'), copyIndex()))]" + } } }, { "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "${azure.apiVersion}", - "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_nic')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic')))]", + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", + "tags": "[parameters('tagsByResource')['${identifier.networkInterfaces}']]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'existing')]", + "name": "[if(equals(copyIndex(),0),variables('name_outputAdminHost_without_pub_ip'),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic_without_pub_ip')))]", "location": "[parameters('location')]", "copy": { - "name": "nicLoop", + "name": "nicLoop_private_ip", "count": "[parameters('numberOfInstances')]" }, "dependsOn": [ @@ -395,22 +607,20 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses',if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_publicIPAddress')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_publicIPAddress'))))]" + "id": "[resourceId('${identifier.publicIPAddresses}',if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_publicIPAddress')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_publicIPAddress'))))]" }, "subnet": { "id": "[variables('ref_subnet')]" } } } - ], - "dnsSettings": { - "internalDnsNameLabel": "[if(equals(copyIndex(),0),parameters('adminVMName'),concat(variables('const_managedVMPrefix'), copyIndex()))]" - } + ] } }, { "type": "Microsoft.Compute/availabilitySets", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForAvailabilitySets}", + "tags": "[parameters('tagsByResource')['${identifier.availabilitySets}']]", "location": "[parameters('location')]", "name": "[variables('name_availabilitySet')]", "properties": { @@ -425,8 +635,9 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "${azure.apiVersion}", + "tags": "[parameters('tagsByResource')['${identifier.virtualMachines}']]", "name": "[if(equals(copyIndex(),0),parameters('adminVMName'),concat(variables('const_managedVMPrefix'), copyIndex()))]", "location": "[parameters('location')]", "copy": { @@ -434,8 +645,10 @@ "count": "[parameters('numberOfInstances')]" }, "dependsOn": [ - "nicLoop", - "[resourceId('Microsoft.Compute/availabilitySets/', variables('name_availabilitySet'))]" + "nicLoop_public_ip", + "nicLoop_private_ip", + "[resourceId('Microsoft.Compute/availabilitySets/', variables('name_availabilitySet'))]", + "[variables('name_privateSaEndpoint')]" ], "identity": "[if(parameters('useSystemAssignedManagedIdentity'), json('{\"type\":\"SystemAssigned\"}'), null())]", "properties": { @@ -463,29 +676,19 @@ "managedDisk": { "storageAccountType": "Standard_LRS" } - }, - "dataDisks": [ - { - "lun": 0, - "createOption": "FromImage", - "diskSizeGB": 900, - "managedDisk": { - "storageAccountType": "Standard_LRS" - } - } - ] + } }, "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces',if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_nic')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic'))))]" + "id": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), resourceId('Microsoft.Network/networkInterfaces',if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_nic_with_pub_ip')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic_with_pub_ip')))), resourceId('Microsoft.Network/networkInterfaces',if(equals(copyIndex(),0),variables('name_outputAdminHost_without_pub_ip'),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic_without_pub_ip')))))]" } ] }, "diagnosticsProfile": { "bootDiagnostics": { "enabled": true, - "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount')), '${azure.apiVersion2}').primaryEndpoints.blob]" + "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount')), '${azure.apiVersionForStorage}').primaryEndpoints.blob]" } } }, @@ -496,8 +699,9 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", + "tags": "[parameters('tagsByResource')['${identifier.virtualMachinesExtensions}']]", "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),'/newuserscript'),concat(variables('const_managedVMPrefix'), copyIndex(),'/newuserscript'))]", "location": "[parameters('location')]", "copy": { @@ -515,17 +719,22 @@ "autoUpgradeMinorVersion": true, "settings": { "fileUris": [ - "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../scripts/', variables('name_scriptFile'), parameters('_artifactsLocationSasToken')))]" + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../scripts/', variables('name_scriptFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameGeneratorscriptFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierJavaFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameValuesTemplate'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierTest'), parameters('_artifactsLocationSasToken')))]" ] }, "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'),' <<< \"',parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',if(equals(copyIndex(),0),'admin',concat(parameters('managedServerPrefix'), copyIndex())),' ',parameters('adminVMName'),' ',variables('const_wlsHome'),' ',variables('name_storageAccount'),' ',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount')), '${azure.apiVersion2}').keys[0].value,' ',variables('const_mountPointPath'),' ',string(parameters('enableHTTPAdminListenPort')),' ','false','\"')]" + "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'),' <<< \"',parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',if(equals(copyIndex(),0),'admin',concat(parameters('managedServerPrefix'), copyIndex())),' ',parameters('adminVMName'),' ',parameters('adminVMNamePrefix'),' ',parameters('_globalResourceNameSuffix'),' ',parameters('numberOfInstances'),' ',variables('const_managedVMPrefix'),' ', parameters('managedServerPrefix'),' ',variables('const_wlsHome'),' ',variables('name_storageAccount'),' ',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount')), '${azure.apiVersionForStorage}').keys[0].value,' ',variables('const_mountPointPath'),' ',string(parameters('enableHTTPAdminListenPort')),' ','false',' ',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), if(parameters('enableDNSConfiguration'),parameters('customDNSNameForAdminServer'),reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn), reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),' ',parameters('dnsLabelPrefix'),' ',parameters('location'), ' ', parameters('virtualNetworkNewOrExisting'),' ',reference(resourceId('Microsoft.Network/privateEndpoints/', variables('name_privateSaEndpoint')), '${azure.apiVersionForPrivateEndpoint}').customDnsConfigs[0].ipAddresses[0],'\"')]" } } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "name": "${cluster.cluster.end}", "dependsOn": [ "virtualMachineExtensionLoop" @@ -542,10 +751,31 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-122130-jdk8-ol74}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141200-jdk21-ol94}", + + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk21-ol94'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141200-jdk21-ol810}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122130-jdk8-ol74'), bool('true'), bool('false'))]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk21-ol810'), bool('true'), bool('false'))]", "dependsOn": [ "virtualMachineExtensionLoop" ], @@ -561,9 +791,11 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-122130-jdk8-ol73}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'from.owls-122130-jdk8-ol73'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141200-jdk17-ol94}", + + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk17-ol94'), bool('true'), bool('false'))]", "dependsOn": [ "virtualMachineExtensionLoop" ], @@ -579,10 +811,11 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-122140-jdk8-ol76}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141200-jdk17-ol810}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'from.owls-122140-jdk8-ol76'), bool('true'), bool('false'))]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk17-ol810'), bool('true'), bool('false'))]", "dependsOn": [ "virtualMachineExtensionLoop" ], @@ -598,9 +831,11 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-141100-jdk8-ol76}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol76'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141100-jdk11-ol91}", + + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol91'), bool('true'), bool('false'))]", "dependsOn": [ "virtualMachineExtensionLoop" ], @@ -616,9 +851,148 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-141100-jdk11-ol76}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol76'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141100-jdk11-ol87}", + + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol87'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141100-jdk8-ol91}", + + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol91'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141100-jdk8-ol87}", + + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol87'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-122140-jdk8-ol91}", + + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-ol91'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-122140-jdk8-ol87}", + + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-ol87'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141100-jdk11-rhel87}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-rhel87'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-141100-jdk8-rhel87}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-rhel87'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "${from.owls-122140-jdk8-rhel87}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-rhel87'), bool('true'), bool('false'))]", "dependsOn": [ "virtualMachineExtensionLoop" ], @@ -636,7 +1010,7 @@ "outputs": { "_adminPublicIPId": { "type": "string", - "value": "[resourceId('Microsoft.Network/publicIPAddresses',concat(parameters('adminVMName'),variables('name_publicIPAddress')))]" + "value": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'),resourceId('Microsoft.Network/publicIPAddresses',concat(parameters('adminVMName'),variables('name_publicIPAddress'))),'')]" }, "artifactsLocationPassedIn": { "type": "string", @@ -644,16 +1018,24 @@ }, "adminHostName": { "type": "string", - "value": "[reference(variables('name_outputAdminHost'), '${azure.apiVersion}').dnsSettings.fqdn]" + "value": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn, reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress)]" }, "adminConsole": { "type": "string", - "value": "[concat('http://',reference(variables('name_outputAdminHost'), '${azure.apiVersion}').dnsSettings.fqdn,':7001/console')]" + "value": "[uri(concat('http://',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'),reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn,reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7001/console/'),'')]" }, "adminSecuredConsole": { "type": "string", - "value": "[concat('https://',reference(variables('name_outputAdminHost'), '${azure.apiVersion}').dnsSettings.fqdn,':7002/console')]" + "value": "[uri(concat('https://',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'),reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn,reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7002/console/'),'')]" + }, + "adminRemoteConsoleURL": { + "type": "string", + "value": "[uri(concat('http://',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'),reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn,reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7001'),'')]" }, + "adminRemoteConsoleSecuredURL": { + "type": "string", + "value": "[uri(concat('https://',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'),reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn,reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7002'),'')]" + }, "wlsDomainLocation": { "type": "string", "value": "[concat('/u01/domains/', parameters('wlsDomainName'))]" diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/coherenceTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/coherenceTemplate.json index 350115ff1..e013979b0 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/coherenceTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/coherenceTemplate.json @@ -22,6 +22,12 @@ }, "defaultValue": "" }, + "_globalResourceNameSuffix":{ + "type": "string", + "metadata": { + "description": "The suffix to be appended to the globally unique resource name" + } + }, "adminPasswordOrKey": { "type": "securestring", "metadata": { @@ -42,6 +48,13 @@ "description": "Virtual machine name of which hosts WebLogic Administration Server." } }, + "adminVMNamePrefix": { + "defaultValue": "adminVM", + "type": "string", + "metadata": { + "description": "Admin Server hosting VM name prefix." + } + }, "authenticationType": { "type": "string", "defaultValue": "password", @@ -59,28 +72,7 @@ "metadata": { "description": "Unique DNS Name for the Public IP used to access the Virtual Machine." } - }, - "elasticsearchEndpoint": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Endpoint of the Elasticsearch instance." - } - }, - "elasticsearchPassword": { - "type": "securestring", - "defaultValue": "[newGuid()]", - "metadata": { - "description": "The credentials to distribute message to Elasticsearch instance with REST API." - } - }, - "elasticsearchUserName": { - "type": "string", - "defaultValue": "elastic", - "metadata": { - "description": "The credentials to distribute message to Elasticsearch instance with REST API." - } - }, + }, "enableCoherenceWebLocalStorage": { "defaultValue": true, "type": "bool", @@ -88,43 +80,23 @@ "description": "Specifies whether Local Storage is enabled for the Coherence*Web cluster tier." } }, - "enableELK": { - "defaultValue": false, - "type": "bool", - "metadata": { - "description": "If true, use the supplied parameters to distribute WebLogic Server logs to the Elasticsearch instance." - } - }, - "guidValue": { - "type": "string", - "defaultValue": "[newGuid()]" - }, "location": { "type": "string", "metadata": { "description": "Location for all resources." } }, - "logIndex": { + "managedServerPrefix": { "type": "string", - "defaultValue": "", - "metadata": { - "description": "Elasticsearch index you expect to export the logs to." - } - }, - "logsToIntegrate": { - "type": "array", - "defaultValue": [ "HTTPAccessLog", "ServerLog", "DomainLog", "DataSourceLog", "StandardErrorAndOutput", "NodeManagerLog" ], - "allowedValues": [ "HTTPAccessLog", "ServerLog", "DomainLog", "DataSourceLog", "StandardErrorAndOutput","NodeManagerLog" ], + "defaultValue": "msp", "metadata": { - "description": "Specify the expeted logs to integrate, you must input at least one log." + "description": "Provide managed server prefix name" } }, - "managedServerPrefix": { + "managedVMNamePrefix": { "type": "string", - "defaultValue": "msp", "metadata": { - "description": "Provide managed server prefix name" + "description": "Managed VM name prefix" } }, "numberOfCoherenceCacheInstances": { @@ -138,13 +110,21 @@ }, "skuUrnVersion": { "type": "string", - "defaultValue": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "defaultValue": "owls-141200-jdk21-ol94;Oracle:weblogic-141200-jdk21-ol94:owls-141200-jdk21-ol94;latest", "allowedValues": [ - "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest", - "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest", - "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest", - "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest", - "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" + "owls-141200-jdk21-ol94;Oracle:weblogic-141200-jdk21-ol94:owls-141200-jdk21-ol94;latest", + "owls-141200-jdk21-ol810;Oracle:weblogic-141200-jdk21-ol810:owls-141200-jdk21-ol810;latest", + "owls-141200-jdk17-ol94;Oracle:weblogic-141200-jdk17-ol94:owls-141200-jdk17-ol94;latest", + "owls-141200-jdk17-ol810;Oracle:weblogic-141200-jdk17-ol810:owls-141200-jdk17-ol810;latest", + "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", + "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest", + "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest", + "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest", + "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest", + "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest", + "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest", + "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest" ], "metadata": { "description": "The Oracle Linux image with Weblogic and Java preinstalled. Semicolon separated string of Sku, URN, and Version" @@ -156,6 +136,20 @@ "description": "Name of storage account. One storage account can store 20 vitual machines with 2 VHDs of 500 IOPS." } }, + "subnetName": { + "type": "string", + "defaultValue": "wls-subnet", + "metadata": { + "description": "Name of the existing or new Subnet" + } + }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, "usePreviewImage": { "type": "bool", "defaultValue": false, @@ -170,6 +164,20 @@ "description": "Select appropriate VM Size for Coherence cache server" } }, + "virtualNetworkResourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "Resource group of Virtual network" + } + }, + "virtualNetworkName": { + "type": "string", + "defaultValue": "wls-vnet", + "metadata": { + "description": "Name of the existing or new VNET" + } + }, "wlsDomainName": { "type": "string", "defaultValue": "wlsd", @@ -190,6 +198,20 @@ "description": "Username for your Weblogic domain name" } }, + "enableDNSConfiguration": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "Boolean value indicating, if DNS Zone Configuration is enabled or not" + } + }, + "customDNSNameForAdminServer": { + "type": "string", + "defaultValue": "none", + "metadata": { + "description": "Custom DNS Name for WebLogic Admin Server" + } + }, "enableCustomSSL":{ "defaultValue":false, "type": "bool", @@ -197,56 +219,56 @@ "description": "Boolean value indicating, if custom SSL is enabled or not" } }, - "keyVaultCustomIdentityKeyStoreData": { + "sslCustomIdentityKeyStoreData": { "type": "securestring", "defaultValue":"", "metadata": { "description": "Weblogic Custom Identity Keystore Data" } }, - "keyVaultCustomIdentityKeyStorePassPhrase": { + "sslCustomIdentityKeyStorePassPhrase": { "type": "securestring", "defaultValue":"", "metadata": { "description": "Weblogic Custom Identity Keystore Passphrase" } }, - "keyVaultCustomIdentityKeyStoreType": { + "sslCustomIdentityKeyStoreType": { "type": "string", "metadata": { "description": "Weblogic Custom Identity Keystore Type" }, "defaultValue": "JKS" }, - "keyVaultCustomTrustKeyStoreData": { + "sslCustomTrustKeyStoreData": { "type": "securestring", "defaultValue":"", "metadata": { "description": "Weblogic Custom Trust Store Data" } }, - "keyVaultCustomTrustKeyStorePassPhrase": { + "sslCustomTrustKeyStorePassPhrase": { "type": "securestring", "defaultValue":"", "metadata": { "description": "Weblogic Custom Trust Store Passphrase" } }, - "keyVaultCustomTrustKeyStoreType": { + "sslCustomTrustKeyStoreType": { "type": "string", "metadata": { "description": "Weblogic Custom Trust Store Type" }, "defaultValue": "JKS" }, - "keyVaultPrivateKeyAlias": { + "sslPrivateKeyAlias": { "type": "string", "defaultValue":"null", "metadata": { "description": "Weblogic Server Private Key Alias" } }, - "keyVaultPrivateKeyPassPhrase": { + "sslPrivateKeyPassPhrase": { "type": "securestring", "defaultValue":"", "metadata": { @@ -271,7 +293,6 @@ }, "const_mountPointPath": "[concat('/mnt/', variables('name_share'))]", "const_publicIPAddressType": "Dynamic", - "const_singleQuote": "'", "const_vmSize": "[parameters('vmSizeSelectForCoherence')]", "const_wlsDomainPath": "/u01/domains", "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", @@ -279,14 +300,17 @@ "name_linuxImageVersion": "[last(split(parameters('skuUrnVersion'),';'))]", "name_nic": "_NIC", "name_publicIPAddress": "_PublicIP", - "name_scriptELKConfiguration": "elkIntegration.sh", "name_scriptFile": "setupCoherence.sh", "name_share": "wlsshare", - "name_subnet": "Subnet", - "name_virtualNetwork": "[concat(parameters('wlsDomainName'),'_VNET')]", - "name_vmMachine": "[concat(parameters('managedServerPrefix'),'StorageVM')]", + "name_subnet": "[parameters('subnetName')]", + "name_virtualNetwork": "[parameters('virtualNetworkName')]", + "name_vmPrefix": "[concat(parameters('managedVMNamePrefix'), 'StorageVM')]", "name_wlsServerPrefix": "[concat(parameters('managedServerPrefix'),'Storage')]", - "ref_subnet": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]" + "ref_subnet": "[resourceId(parameters('virtualNetworkResourceGroupName'),'Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]", + "name_customHostnameGeneratorscriptFile": "generateCustomHostNameVerifier.sh", + "name_customHostnameVerifierJavaFile": "src/main/java/WebLogicCustomHostNameVerifier.java", + "name_customHostnameValuesTemplate": "src/main/java/HostNameValuesTemplate.txt", + "name_customHostnameVerifierTest" : "src/test/java/WebLogicCustomHostNameVerifierTest.java" }, "functions": [ { @@ -309,9 +333,10 @@ ], "resources": [ { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${cluster.coherence.start}", "type": "Microsoft.Resources/deployments", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "properties": { "mode": "Incremental", "template": { @@ -323,9 +348,10 @@ } }, { + "apiVersion": "${azure.apiVersionForPublicIPAddresses}", "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(variables('name_vmMachine'),copyIndex(1),variables('name_publicIPAddress'))]", + "tags": "[parameters('tagsByResource')['${identifier.publicIPAddresses}']]", + "name": "[concat(variables('name_vmPrefix'),copyIndex(1),variables('name_publicIPAddress'))]", "location": "[parameters('location')]", "copy": { "name": "publicIPLoop", @@ -334,27 +360,28 @@ "properties": { "publicIPAllocationMethod": "[variables('const_publicIPAddressType')]", "dnsSettings": { - "domainNameLabel": "[concat(toLower(parameters('dnsLabelPrefix')),copyindex(1),'-',take(replace(parameters('guidValue'),'-',''),10),'-',toLower(parameters('wlsDomainName')))]" + "domainNameLabel": "[take(concat(toLower(parameters('dnsLabelPrefix')), 'co', copyindex(),'-', parameters('_globalResourceNameSuffix'),'-',toLower(parameters('wlsDomainName'))), 50)]" } } }, { + "apiVersion": "${azure.apiVersionForVirtualNetworks}", "type": "Microsoft.Network/virtualNetworks/subnets", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_virtualNetwork'), '/', variables('name_subnet'))]", "condition": "[and(empty(variables('name_virtualNetwork')), empty(variables('name_subnet')))]" }, { + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(variables('name_vmMachine'), copyIndex(1), variables('name_nic'))]", + "tags": "[parameters('tagsByResource')['${identifier.networkInterfaces}']]", + "name": "[concat(variables('name_vmPrefix'), copyIndex(1), variables('name_nic'))]", "location": "[parameters('location')]", "copy": { "name": "nicLoop", "count": "[parameters('numberOfCoherenceCacheInstances')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/publicIPAddresses/', concat(variables('name_vmMachine'),copyIndex(1),variables('name_publicIPAddress')))]" + "[resourceId('Microsoft.Network/publicIPAddresses/', concat(variables('name_vmPrefix'),copyIndex(1),variables('name_publicIPAddress')))]" ], "properties": { "ipConfigurations": [ @@ -363,7 +390,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses',concat(variables('name_vmMachine'),copyIndex(1),variables('name_publicIPAddress')))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses',concat(variables('name_vmPrefix'),copyIndex(1),variables('name_publicIPAddress')))]" }, "subnet": { "id": "[variables('ref_subnet')]" @@ -372,14 +399,15 @@ } ], "dnsSettings": { - "internalDnsNameLabel": "[concat(variables('name_vmMachine'), copyIndex(1))]" + "internalDnsNameLabel": "[concat(variables('name_vmPrefix'), copyIndex(1))]" } } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(variables('name_vmMachine'), copyIndex(1))]", + "tags": "[parameters('tagsByResource')['${identifier.virtualMachines}']]", + "name": "[concat(variables('name_vmPrefix'), copyIndex(1))]", "location": "[parameters('location')]", "copy": { "name": "virtualMachineLoop", @@ -393,7 +421,7 @@ "vmSize": "[variables('const_vmSize')]" }, "osProfile": { - "computerName": "[concat(variables('name_vmMachine'), copyIndex(1))]", + "computerName": "[concat(variables('name_vmPrefix'), copyIndex(1))]", "adminUsername": "[parameters('adminUsername')]", "adminPassword": "[parameters('adminPasswordOrKey')]", "linuxConfiguration": "[if(equals(parameters('authenticationType'), 'password'), json('null'), variables('const_linuxConfiguration'))]" @@ -410,29 +438,19 @@ "managedDisk": { "storageAccountType": "Standard_LRS" } - }, - "dataDisks": [ - { - "lun": 0, - "createOption": "FromImage", - "diskSizeGB": 900, - "managedDisk": { - "storageAccountType": "Standard_LRS" - } - } - ] + } }, "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('name_vmMachine'), copyIndex(1), variables('name_nic')))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('name_vmPrefix'), copyIndex(1), variables('name_nic')))]" } ] }, "diagnosticsProfile": { "bootDiagnostics": { "enabled": true, - "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', parameters('storageAccountName')), '${azure.apiVersion2}').primaryEndpoints.blob]" + "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', parameters('storageAccountName')), '${azure.apiVersionForStorage}').primaryEndpoints.blob]" } } }, @@ -444,8 +462,9 @@ }, { "type": "Microsoft.Compute/virtualMachines/extensions", - "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),'/newuserscript'),concat(variables('name_vmMachine'), copyIndex(),'/newuserscript'))]", - "apiVersion": "${azure.apiVersion}", + "tags": "[parameters('tagsByResource')['${identifier.virtualMachinesExtensions}']]", + "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),'/newuserscript'),concat(variables('name_vmPrefix'), copyIndex(),'/newuserscript'))]", + "apiVersion": "${azure.apiVersionForVirtualMachines}", "location": "[parameters('location')]", "copy": { "name": "virtualMachineExtensionLoop", @@ -462,18 +481,22 @@ "settings": { "fileUris": [ "[uri(parameters('_artifactsLocationCoherenceTemplate'), concat('../scripts/', variables('name_scriptFile'), parameters('_artifactsLocationSasToken')))]", - "[uri(parameters('_artifactsLocationCoherenceTemplate'), concat('../scripts/', variables('name_scriptELKConfiguration'), parameters('_artifactsLocationSasToken')))]" + "[uri(parameters('_artifactsLocationCoherenceTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameGeneratorscriptFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationCoherenceTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierJavaFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationCoherenceTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameValuesTemplate'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationCoherenceTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierTest'), parameters('_artifactsLocationSasToken')))]" ] }, "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'), ' <<< \"',parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ', parameters('adminVMName'),' ',variables('const_wlsHome'),' ',variables('const_wlsDomainPath'),' ', parameters('storageAccountName'),' ',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '${azure.apiVersion2}').keys[0].value,' ', variables('const_mountPointPath'),' ', parameters('enableCoherenceWebLocalStorage'),' ',parameters('enableELK'),' ',variables('const_singleQuote'),parameters('elasticsearchEndpoint'),variables('const_singleQuote'),' ',variables('const_singleQuote'),parameters('elasticsearchUserName'),variables('const_singleQuote'),' ',variables('const_singleQuote'),parameters('elasticsearchPassword'),variables('const_singleQuote'),' ',array.join(parameters('logsToIntegrate')),' ',variables('const_singleQuote'),parameters('logIndex'),variables('const_singleQuote'),' ',variables('name_wlsServerPrefix'),' ',copyIndex(),' ',string(parameters('enableCustomSSL')),' ',base64(parameters('keyVaultCustomIdentityKeyStoreData')),' ',base64(parameters('keyVaultCustomIdentityKeyStorePassPhrase')),' ',base64(parameters('keyVaultCustomIdentityKeyStoreType')),' ',base64(parameters('keyVaultCustomTrustKeyStoreData')),' ',base64(parameters('keyVaultCustomTrustKeyStorePassPhrase')),' ',base64(parameters('keyVaultCustomTrustKeyStoreType')),' ',base64(parameters('keyVaultPrivateKeyAlias')),' ',base64(parameters('keyVaultPrivateKeyPassPhrase')),'\"')]" + "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'), ' <<< \"', parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ', parameters('adminVMName'),' ',parameters('adminVMNamePrefix'),' ',parameters('_globalResourceNameSuffix'),' ',parameters('numberOfCoherenceCacheInstances'),' ',variables('name_vmPrefix'),' ',variables('const_wlsHome'),' ',variables('const_wlsDomainPath'),' ', parameters('storageAccountName'),' ',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '${azure.apiVersionForStorage}').keys[0].value,' ', variables('const_mountPointPath'),' ', parameters('enableCoherenceWebLocalStorage'),' ',variables('name_wlsServerPrefix'),' ',copyIndex(),' ',if(parameters('enableDNSConfiguration'),parameters('customDNSNameForAdminServer'),parameters('adminVMName')),' ',parameters('dnsLabelPrefix'),' ',parameters('location'),' ','False',' ',string(parameters('enableCustomSSL')),' ',base64(parameters('sslCustomIdentityKeyStoreData')),' ',base64(parameters('sslCustomIdentityKeyStorePassPhrase')),' ',base64(parameters('sslCustomIdentityKeyStoreType')),' ',base64(parameters('sslCustomTrustKeyStoreData')),' ',base64(parameters('sslCustomTrustKeyStorePassPhrase')),' ',base64(parameters('sslCustomTrustKeyStoreType')),' ',base64(parameters('sslPrivateKeyAlias')),' ',base64(parameters('sslPrivateKeyPassPhrase')),'\"')]" } } }, { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${cluster.coherence.end}", "type": "Microsoft.Resources/deployments", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "dependsOn": [ "virtualMachineExtensionLoop" ], diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/dbTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/dbTemplate.json index a13e5680e..f5beb33c8 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/dbTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/dbTemplate.json @@ -1,209 +1,332 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "_artifactsLocation": { - "type": "string", - "metadata": { - "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." - } - }, - "_artifactsLocationDbTemplate": { - "defaultValue": "[if(contains(parameters('_artifactsLocation'), 'githubusercontent'), parameters('_artifactsLocation'), deployment().properties.templateLink.uri)]", - "type": "string", - "metadata": { - "description": "If we are deploying from the command line, use the passed in _artifactsLocation, otherwise use the default." - } - }, - "_artifactsLocationSasToken": { - "type": "securestring", - "metadata": { - "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." - }, - "defaultValue": "" - }, - "adminVMName": { - "defaultValue": "adminVM", - "type": "string", - "metadata": { - "description": "Admin Server hosting VM name." - } - }, - "databaseType": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "One of the supported database types" - } - }, - "dsConnectionURL": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "JDBC Connection String" - } - }, - "dbUser": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "Userid of Database" - } - }, - "dbPassword": { - "type": "securestring", - "metadata": { - "description": "Password for Database" - } - }, - "jdbcDataSourceName": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "JNDI Name for JDBC Datasource" - } - }, - "location": { - "type": "string", - "metadata": { - "description": "Location for all resources." - } - }, - "wlsUserName": { - "defaultValue": "weblogic", - "type": "string", - "metadata": { - "description": "Username for your Weblogic domain name" - } - }, - "wlsPassword": { - "type": "securestring", - "metadata": { - "description": "Password for your Weblogic domain name" - } - } - }, - "variables": { - "const_wlsAdminPort": "7005", - "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", - "name_scriptFilePrefix": "datasourceConfig-", - "name_scriptFileSuffix-sqlserver": "sqlserver.sh", - "name_scriptFileSuffix-oracle": "oracle.sh", - "name_scriptFileSuffix-postgresql": "postgresql.sh" - }, - "resources": [ - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${cluster.database.start}", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(parameters('adminVMName'),'/newuserscript')]", - "location": "[parameters('location')]", - "properties": { - "publisher": "Microsoft.Azure.Extensions", - "type": "CustomScript", - "typeHandlerVersion": "2.0", - "autoUpgradeMinorVersion": true, - "settings": { - "fileUris": [ - "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-sqlserver'), parameters('_artifactsLocationSasToken')))]", - "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-oracle'), parameters('_artifactsLocationSasToken')))]", - "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-postgresql'), parameters('_artifactsLocationSasToken')))]" - ] - }, - "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptFilePrefix'),parameters('databaseType'),'.sh <<< \"',variables('const_wlsHome'),' ',parameters('adminVMName'),' ',variables('const_wlsAdminPort'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('jdbcDataSourceName'),' ',parameters('dsConnectionURL'),' ',parameters('dbUser'),' ',parameters('dbPassword'),'\"')]" - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${cluster.database.end}", - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" - ], - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${database.oracle}", - "condition": "[if(contains(parameters('databaseType'), 'oracle'), bool('true'), bool('false'))]", - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" - ], - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${database.postgresql}", - "condition": "[if(contains(parameters('databaseType'), 'postgresql'), bool('true'), bool('false'))]", - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" - ], - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${database.sqlserver}", - "condition": "[if(contains(parameters('databaseType'), 'sqlserver'), bool('true'), bool('false'))]", - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" - ], - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - } - ], - "outputs": { - "artifactsLocationPassedIn": { - "type": "string", - "value": "[parameters('_artifactsLocation')]" - } - } -} +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." + } + }, + "_artifactsLocationSasToken": { + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." + }, + "defaultValue": "" + }, + "adminVMName": { + "type": "string", + "defaultValue": "adminVM", + "metadata": { + "description": "Admin Server hosting VM name." + } + }, + "databaseType": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "One of the supported database types" + } + }, + "dbGlobalTranPro": { + "defaultValue": "OnePhaseCommit", + "type": "string", + "metadata": { + "description": "Determines the transaction protocol (global transaction processing behavior) for the data source." + } + }, + "dbIdentity": { + "defaultValue": {}, + "type": "object", + "metadata": { + "description": "Managed identity that has access to the data source." + } + }, + "dbPassword": { + "defaultValue": "[newGuid()]", + "type": "securestring", + "metadata": { + "description": "Password for Database" + } + }, + "dbUser": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Userid of Database" + } + }, + "dsConnectionURL": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "JDBC Connection String" + } + }, + "enablePswlessConnection": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "True to enable passwordless connection." + } + }, + "jdbcDataSourceName": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "JNDI Name for JDBC Datasource" + } + }, + "location": { + "type": "string", + "metadata": { + "description": "Location for all resources." + } + }, + "managedServerPrefix": { + "type": "string", + "defaultValue": "msp", + "metadata": { + "description": "Provide managed server prefix name" + } + }, + "managedVMNamePrefix": { + "type": "string", + "metadata": { + "description": "Provide managed VM prefix name" + } + }, + "numberOfManagedApplicationInstances": { + "type": "int", + "defaultValue": 2, + "minValue": 1, + "maxValue": 20, + "metadata": { + "description": "Number of VMs that have been deployed to host managed application server." + } + }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, + "wlsDomainName": { + "type": "string", + "defaultValue": "wlsd", + "metadata": { + "description": "Provide Weblogic domain name" + } + }, + "wlsPassword": { + "type": "securestring", + "metadata": { + "description": "Password for your Weblogic domain name" + } + }, + "wlsUserName": { + "type": "string", + "metadata": { + "description": "Username for your Weblogic domain name" + } + } + }, + "variables": { + "name_dbLinkedTemplateName": "_dbTemplate.json", + "name_dbPswlessTemplateName": "_pswlessDbTemplate.json", + "name_dbUpgradeMySQLDriver": "_installJdbcLibsTemplate.json" + }, + "resources": [ + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "name": "pswlessDbTemplate", + "condition": "[parameters('enablePswlessConnection')]", + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_dbPswlessTemplateName')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + }, + "adminVMName": { + "value": "[parameters('adminVMName')]" + }, + "databaseType": { + "value": "[parameters('databaseType')]" + }, + "dbGlobalTranPro": { + "value": "[parameters('dbGlobalTranPro')]" + }, + "dbIdentity": { + "value": "[parameters('dbIdentity')]" + }, + "dbUser": { + "value": "[parameters('dbUser')]" + }, + "dsConnectionURL": { + "value": "[parameters('dsConnectionURL')]" + }, + "jdbcDataSourceName": { + "value": "[parameters('jdbcDataSourceName')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "managedServerPrefix": { + "value": "[parameters('managedServerPrefix')]" + }, + "managedVMNamePrefix": { + "value": "[parameters('managedVMNamePrefix')]" + }, + "numberOfManagedApplicationInstances": { + "value": "[parameters('numberOfManagedApplicationInstances')]" + }, + "tagsByResource": { + "value": "[parameters('tagsByResource')]" + }, + "wlsDomainName": { + "value": "[parameters('wlsDomainName')]" + }, + "wlsPassword": { + "value": "[parameters('wlsPassword')]" + }, + "wlsUserName": { + "value": "[parameters('wlsUserName')]" + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "upgradeMySQLJdbcDriverTemplate", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[and(not(parameters('enablePswlessConnection')), equals(parameters('databaseType'),'mysql'))]", + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_dbUpgradeMySQLDriver')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + }, + "adminVMName": { + "value": "[parameters('adminVMName')]" + }, + "databaseType": { + "value": "[parameters('databaseType')]" + }, + "enablePswlessConnection": { + "value": "[parameters('enablePswlessConnection')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "managedServerPrefix": { + "value": "[parameters('managedServerPrefix')]" + }, + "managedVMNamePrefix": { + "value": "[parameters('managedVMNamePrefix')]" + }, + "numberOfManagedApplicationInstances": { + "value": "[parameters('numberOfManagedApplicationInstances')]" + }, + "tagsByResource": { + "value": "[parameters('tagsByResource')]" + }, + "wlsDomainName": { + "value": "[parameters('wlsDomainName')]" + }, + "wlsPassword": { + "value": "[parameters('wlsPassword')]" + }, + "wlsUserName": { + "value": "[parameters('wlsUserName')]" + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "passwordDatasourceDeployment", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", + "condition": "[not(parameters('enablePswlessConnection'))]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'upgradeMySQLJdbcDriverTemplate')]" + ], + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_dbLinkedTemplateName')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + }, + "adminVMName": { + "value": "[parameters('adminVMName')]" + }, + "databaseType": { + "value": "[parameters('databaseType')]" + }, + "dbGlobalTranPro": { + "value": "[parameters('dbGlobalTranPro')]" + }, + "dbPassword": { + "value": "[parameters('dbPassword')]" + }, + "dbUser": { + "value": "[parameters('dbUser')]" + }, + "dsConnectionURL": { + "value": "[parameters('dsConnectionURL')]" + }, + "enablePswlessConnection": { + "value": "[parameters('enablePswlessConnection')]" + }, + "jdbcDataSourceName": { + "value": "[parameters('jdbcDataSourceName')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "tagsByResource": { + "value": "[parameters('tagsByResource')]" + }, + "wlsPassword": { + "value": "[parameters('wlsPassword')]" + }, + "wlsUserName": { + "value": "[parameters('wlsUserName')]" + } + } + } + } + ], + "outputs": { + "artifactsLocationPassedIn": { + "type": "string", + "value": "[parameters('_artifactsLocation')]" + } + } +} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/dnszonesTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/dnszonesTemplate.json index 2a383c2c1..9ee842405 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/dnszonesTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/dnszonesTemplate.json @@ -15,6 +15,12 @@ "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." } }, + "_globalResourceNameSuffix": { + "type": "string", + "metadata": { + "description": "A unique suffix that was specified during the deployment of the solution template." + } + }, "dnszonesARecordSetNames": { "type": "array", "defaultValue": [], @@ -57,12 +63,6 @@ "description": "If true, update A records in the existing DNS Zone, otherwise, create a new DNS Zone and ." } }, - "identity": { - "type": "Object", - "metadata": { - "description": "Managed identity to be used for the deployment script. Currently, only user-assigned MSI is supported." - } - }, "location": { "type": "string", "metadata": { @@ -83,6 +83,13 @@ "description": "References to Azure resources from where the DNS resource value is taken. Each item is corresponding to values of dnszonesARecordSetNames." } }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, "ttl": { "type": "int", "defaultValue": 3600, @@ -105,22 +112,23 @@ }, "resources": [ { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${cluster.dns.start}", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "type": "Microsoft.Resources/deployments", "properties": { "mode": "Incremental", "template": { "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", - "resources": [ - ] + "resources": [] } } }, { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "type": "Microsoft.Resources/deployments", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "name": "createDNSZone", "condition": "[not(parameters('hasDNSZones'))]", "properties": { @@ -148,6 +156,9 @@ "targetResources": { "value": "[parameters('targetResources')]" }, + "tagsByResource": { + "value": "[parameters('tagsByResource')]" + }, "ttl": { "value": "[parameters('ttl')]" } @@ -155,8 +166,9 @@ } }, { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "type": "Microsoft.Resources/deployments", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "name": "updateDNSZone", "condition": "[parameters('hasDNSZones')]", "properties": { @@ -172,6 +184,9 @@ "_artifactsLocationSasToken": { "value": "[parameters('_artifactsLocationSasToken')]" }, + "_globalResourceNameSuffix": { + "value": "[parameters('_globalResourceNameSuffix')]" + }, "dnszonesARecordSetNames": { "value": "[parameters('dnszonesARecordSetNames')]" }, @@ -184,9 +199,6 @@ "dnszoneName": { "value": "[parameters('dnszoneName')]" }, - "identity": { - "value": "[parameters('identity')]" - }, "location": { "value": "[parameters('location')]" }, @@ -196,6 +208,9 @@ "targetResources": { "value": "[parameters('targetResources')]" }, + "tagsByResource": { + "value": "[parameters('tagsByResource')]" + }, "ttl": { "value": "[parameters('ttl')]" }, @@ -206,20 +221,19 @@ } }, { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${cluster.dns.end}", "type": "Microsoft.Resources/deployments", + "tags": "[parameters('tagsByResource')['${identifier.resourcesDeployment}']]", "properties": { "mode": "Incremental", "template": { "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", - "resources": [ - ] + "resources": [] } } } ], - "outputs": { - } -} + "outputs": {} +} \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/elkNestedTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/elkNestedTemplate.json deleted file mode 100644 index 64c4ead8d..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/elkNestedTemplate.json +++ /dev/null @@ -1,263 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "_artifactsLocation": { - "type": "string", - "metadata": { - "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." - } - }, - "_artifactsLocationELKTemplate": { - "defaultValue": "[if(contains(parameters('_artifactsLocation'), 'githubusercontent'), parameters('_artifactsLocation'), deployment().properties.templateLink.uri)]", - "type": "string", - "metadata": { - "description": "If we are deploying from the command line, use the passed in _artifactsLocation, otherwise use the default." - } - }, - "_artifactsLocationSasToken": { - "defaultValue": "", - "type": "securestring", - "metadata": { - "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." - } - }, - "adminVMName": { - "type": "string", - "defaultValue": "adminVM", - "metadata": { - "description": "Admin Server hosting VM name." - } - }, - "elasticsearchEndpoint": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Endpoint of the Elasticsearch instance." - } - }, - "elasticsearchPassword": { - "type": "securestring", - "defaultValue": "[newGuid()]", - "metadata": { - "description": "The credentials to distibute message with REST API to Elasticsearch instance." - } - }, - "elasticsearchUserName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "The credentials to distibute message with REST API to Elasticsearch instance." - } - }, - "guidValue": { - "type": "string", - "defaultValue": "[newGuid()]" - }, - "location": { - "type": "string", - "metadata": { - "description": "Location for all resources." - } - }, - "logsToIntegrate": { - "type": "array", - "defaultValue": [ "HTTPAccessLog", "ServerLog", "DomainLog", "DataSourceLog", "StandardErrorAndOutput", "NodeManagerLog" ], - "allowedValues": [ "HTTPAccessLog", "ServerLog", "DomainLog", "DataSourceLog", "StandardErrorAndOutput", "NodeManagerLog" ], - "metadata": { - "description": "Specify the expeted logs to integrate, you must input at least one log." - } - }, - "managedServerPrefix": { - "type": "string", - "defaultValue": "msp", - "metadata": { - "description": "Provide managed server prefix name" - } - }, - "numberOfManagedApplicationInstances": { - "type": "int", - "defaultValue": 2, - "minValue": 1, - "maxValue": 20, - "metadata": { - "description": "Number of VMs that have been deployed to host managed application server." - } - }, - "numberOfManagedCacheInstances": { - "type": "int", - "defaultValue": 0, - "minValue": 0, - "maxValue": 20, - "metadata": { - "description": "Number of VMs that have been deployed to host managed cache server, please set the value if your cluster is Coherence cluster." - } - }, - "wlsDomainName": { - "type": "string", - "defaultValue": "wlsd", - "metadata": { - "description": "Provide Weblogic domain name" - } - }, - "wlsPassword": { - "type": "securestring", - "metadata": { - "description": "Password for your Weblogic domain name" - } - }, - "wlsUserName": { - "type": "string", - "metadata": { - "description": "Username for your Weblogic domain name" - } - } - }, - "variables": { - "const_adminServerName": "admin", - "const_logIndex": "[concat('azure-weblogic-cluster-', parameters('guidValue'))]", - "const_managedCacheVMPrefix": "[concat(parameters('managedServerPrefix'),'StorageVM')]", - "const_managedVMPrefix": "[concat(parameters('managedServerPrefix'),'VM')]", - "const_wlsAdminPort": "7005", - "const_wlsDomainPath": "[concat('/u01/domains/', parameters('wlsDomainName'))]", - "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", - "name_scriptELKConfiguration": "elkIntegration.sh" - }, - "functions": [ - { - "namespace": "array", - "members": { - "join": { - "parameters": [ - { - "name": "items", - "type": "array" - } - ], - "output": { - "type": "string", - "value": "[replace(replace(replace(string(parameters('items')), '[\"', ''), '\"]', ''), '\",\"', ',')]" - } - } - } - } - ], - "resources": [ - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${cluster.elk.start}", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(parameters('adminVMName'),'/newuserscript')]", - "location": "[parameters('location')]", - "properties": { - "publisher": "Microsoft.Azure.Extensions", - "type": "CustomScript", - "typeHandlerVersion": "2.0", - "autoUpgradeMinorVersion": true, - "settings": { - "fileUris": [ - "[uri(parameters('_artifactsLocationELKTemplate'), concat('../scripts/', variables('name_scriptELKConfiguration'), parameters('_artifactsLocationSasToken')))]" - ] - }, - "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptELKConfiguration'),' ', variables('const_wlsHome'), ' ', concat(parameters('adminVMName'), ':', variables('const_wlsAdminPort')), ' ', parameters('wlsUserName'), ' ', parameters('wlsPassword'), ' ', variables('const_adminServerName'), ' ', parameters('elasticsearchEndpoint'),' ', parameters('elasticsearchUserName'),' ', parameters('elasticsearchPassword'), ' ', parameters('wlsDomainName'),' ', variables('const_wlsDomainPath'),' ', array.join(parameters('logsToIntegrate')), ' ',0, ' ', variables('const_logIndex'), ' ', parameters('managedServerPrefix'))]" - } - } - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(variables('const_managedVMPrefix'), copyIndex(1),'/newuserscript')]", - "location": "[parameters('location')]", - "copy": { - "name": "appVirtualMachineExtensionLoop", - "count": "[parameters('numberOfManagedApplicationInstances')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" - ], - "properties": { - "publisher": "Microsoft.Azure.Extensions", - "type": "CustomScript", - "typeHandlerVersion": "2.0", - "autoUpgradeMinorVersion": true, - "settings": { - "fileUris": [ - "[uri(parameters('_artifactsLocationELKTemplate'), concat('../scripts/', variables('name_scriptELKConfiguration'), parameters('_artifactsLocationSasToken')))]" - ] - }, - "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptELKConfiguration'),' ', variables('const_wlsHome'), ' ', concat(parameters('adminVMName'), ':', variables('const_wlsAdminPort')), ' ', parameters('wlsUserName'), ' ', parameters('wlsPassword'), ' ', variables('const_adminServerName'), ' ', parameters('elasticsearchEndpoint'),' ', parameters('elasticsearchUserName'),' ', parameters('elasticsearchPassword'), ' ', parameters('wlsDomainName'),' ', variables('const_wlsDomainPath'),' ', array.join(parameters('logsToIntegrate')), ' ',copyIndex(1), ' ', variables('const_logIndex'), ' ', parameters('managedServerPrefix'))]" - } - } - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(variables('const_managedCacheVMPrefix'), copyIndex(1),'/newuserscript')]", - "location": "[parameters('location')]", - "copy": { - "name": "cacheVirtualMachineExtensionLoop", - "count": "[parameters('numberOfManagedCacheInstances')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" - ], - "properties": { - "publisher": "Microsoft.Azure.Extensions", - "type": "CustomScript", - "typeHandlerVersion": "2.0", - "autoUpgradeMinorVersion": true, - "settings": { - "fileUris": [ - "[uri(parameters('_artifactsLocationELKTemplate'), concat('../scripts/', variables('name_scriptELKConfiguration'), parameters('_artifactsLocationSasToken')))]" - ] - }, - "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptELKConfiguration'),' <<< \"', variables('const_wlsHome'), ' ', concat(parameters('adminVMName'), ':', variables('const_wlsAdminPort')), ' ', parameters('wlsUserName'), ' ', parameters('wlsPassword'), ' ', variables('const_adminServerName'), ' ', parameters('elasticsearchEndpoint'),' ', parameters('elasticsearchUserName'),' ', parameters('elasticsearchPassword'), ' ', parameters('wlsDomainName'),' ', variables('const_wlsDomainPath'),' ', array.join(parameters('logsToIntegrate')), ' ',copyIndex(1), ' ', variables('const_logIndex'), ' ', concat(parameters('managedServerPrefix'), 'Storage'),'\"')]" - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${cluster.elk.end}", - "dependsOn": [ - "appVirtualMachineExtensionLoop", - "cacheVirtualMachineExtensionLoop" - ], - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - } - ], - "outputs": { - "artifactsLocationPassedIn": { - "type": "string", - "value": "[parameters('_artifactsLocation')]" - }, - "logIndex": { - "type": "string", - "value": "[variables('const_logIndex')]" - } - } -} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/nsgNestedTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/nsgNestedTemplate.json index e4dbbdc10..462b9487d 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/nsgNestedTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/nsgNestedTemplate.json @@ -29,7 +29,7 @@ "type": "Microsoft.Network/networkSecurityGroups/securityRules", "name": "[concat(parameters('networkSecurityGroupName'),'/','WebLogicAdminPortsAllowed')]", "condition": "[not(parameters('denyPublicTrafficForAdminServer'))]", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForNetworkSecurityGroups}", "properties": { "protocol": "TCP", "sourcePortRange": "*", @@ -48,7 +48,7 @@ "type": "Microsoft.Network/networkSecurityGroups/securityRules", "name": "[concat(parameters('networkSecurityGroupName'),'/','WebLogicAdminPortsDenied')]", "condition": "[parameters('denyPublicTrafficForAdminServer')]", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForNetworkSecurityGroups}", "properties": { "protocol": "*", "sourcePortRange": "*", @@ -67,7 +67,7 @@ "type": "Microsoft.Network/networkSecurityGroups/securityRules", "name": "[concat(parameters('networkSecurityGroupName'),'/','WebLogiManagedPortsAllowed')]", "condition": "[and(not(parameters('denyPublicTrafficForManagedServer')), parameters('enableAppGateway'))]", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForNetworkSecurityGroups}", "properties": { "protocol": "*", "sourcePortRange": "*", @@ -85,7 +85,7 @@ "type": "Microsoft.Network/networkSecurityGroups/securityRules", "name": "[concat(parameters('networkSecurityGroupName'),'/','WebLogiManagedPortsDenied')]", "condition": "[and(parameters('denyPublicTrafficForManagedServer'), parameters('enableAppGateway'))]", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForNetworkSecurityGroups}", "properties": { "protocol": "*", "sourcePortRange": "*", diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/postDeploymentTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/postDeploymentTemplate.json new file mode 100644 index 000000000..98adee5f9 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/postDeploymentTemplate.json @@ -0,0 +1,107 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "metadata": { + "description": "Location for all resources." + } + }, + "_globalResourceNameSuffix": { + "type": "string", + "metadata": { + "description": "A unique suffix that was specified during the deployment of the solution template." + } + }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, + "const_guidTag" :{ + "type": "string", + "metadata": { + "description": "A unique tag for resources." + } + }, + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." + } + }, + "_artifactsLocationAdminTemplate": { + "defaultValue": "[if(contains(parameters('_artifactsLocation'), 'githubusercontent'), parameters('_artifactsLocation'), deployment().properties.templateLink.uri)]", + "type": "string", + "metadata": { + "description": "If we are deploying from the command line, use the passed in _artifactsLocation, otherwise use the default." + } + }, + "_artifactsLocationSasToken": { + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." + } + }, + "userAssignedIdentityResourceId":{ + "type": "string", + "metadata": { + "Description": "UserAssigned Identity" + } + }, + "utcValue": { + "type": "string", + "defaultValue": "[utcNow()]" + } + }, + "variables": { + "name_postDeploymentscriptFile": "postDeploymentScript.sh" + }, + "resources": [ + { + "type": "${identifier.deploymentScripts}", + "apiVersion": "${azure.apiVersionForDeploymentScript}", + "tags": "[parameters('tagsByResource')['${identifier.deploymentScripts}']]", + "name": "[concat('postdeployscript-', parameters('_globalResourceNameSuffix'))]", + "kind": "AzureCLI", + "location": "[parameters('location')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[parameters('userAssignedIdentityResourceId')]": {} + } + }, + "properties": { + "forceUpdateTag": "[parameters('utcValue')]", + "azCliVersion": "2.9.1", + "timeout": "PT30M", + "cleanupPreference": "OnSuccess", + "retentionInterval": "P1D", + "primaryScriptUri": "[uri(parameters('_artifactsLocationAdminTemplate'), concat('../scripts/', variables('name_postDeploymentscriptFile'), parameters('_artifactsLocationSasToken')))]", + "environmentVariables": [ + { + "name": "MANAGED_IDENTITY_ID", + "value": "[parameters('userAssignedIdentityResourceId')]" + }, + { + "name": "RESOURCE_GROUP_NAME", + "value": "[resourceGroup().name]" + }, + { + "name": "GUID_TAG", + "value": "[parameters('const_guidTag')]" + } + ] + } + } + ], + "outputs": { + "userAssignedIdentityResource": { + "type": "string", + "value": "[parameters('userAssignedIdentityResourceId')]" + } + } +} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/postDeploymentUAMIRolesTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/postDeploymentUAMIRolesTemplate.json new file mode 100644 index 000000000..2f0cb1387 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/arm/nestedtemplates/postDeploymentUAMIRolesTemplate.json @@ -0,0 +1,109 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "metadata": { + "description": "Location for all resources." + } + }, + "_globalResourceNameSuffix": { + "type": "string", + "metadata": { + "description": "A unique suffix that was specified during the deployment of the solution template." + } + }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, + "roleAssignmentNameSeed": { + "type": "string", + "defaultValue": "[guid(subscription().id, parameters('_globalResourceNameSuffix'))]", + "metadata": { + "description": "A unique string used to generate the role assignment name. Defaults to a unique GUID based on the deployment context." + } + } + }, + "variables": { + "const_roleDefinitionIdOfContributor": "b24988ac-6180-42a0-ab88-20f7382dd24c", + "name_postDeploymentScriptUserDefinedManagedIdentity": "[concat('post-deployment-user-defined-managed-identity', parameters('_globalResourceNameSuffix'))]", + "name_postDeploymentScriptRoleAssignment": "[concat('post-deployment-user-defined-role-assignment', parameters('_globalResourceNameSuffix'))]" + }, + "resources": [ + { + "type": "${identifier.userAssignedIdentities}", + "apiVersion": "${azure.apiVersionForIdentity}", + "tags": "[parameters('tagsByResource')['${identifier.userAssignedIdentities}']]", + "name": "[variables('name_postDeploymentScriptUserDefinedManagedIdentity')]", + "location": "[parameters('location')]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "[variables('name_postDeploymentScriptRoleAssignment')]", + "location": "[parameters('location')]", + "subscriptionId": "[subscription().subscriptionId]", + "dependsOn": [ + "[resourceId('${identifier.userAssignedIdentities}', variables('name_postDeploymentScriptUserDefinedManagedIdentity'))]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "innerPrincipalId": { + "type": "string" + }, + "innerRoleDefinitionId": { + "type": "string" + }, + "innerRoleAssignmentNameSeed": { + "type": "string" + } + }, + "variables": { + "roleAssignmentGuid": "[guid(parameters('innerRoleAssignmentNameSeed'))]" + }, + "resources": [ + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "${azure.apiVersionForRoleAssignment}", + "name": "[variables('roleAssignmentGuid')]", + "properties": { + "roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', parameters('innerRoleDefinitionId'))]", + "principalId": "[parameters('innerPrincipalId')]", + "principalType": "ServicePrincipal" + } + } + ] + }, + "parameters": { + "innerPrincipalId": { + "value": "[reference(resourceId('${identifier.userAssignedIdentities}',variables('name_postDeploymentScriptUserDefinedManagedIdentity'))).principalId]" + }, + "innerRoleDefinitionId": { + "value": "[variables('const_roleDefinitionIdOfContributor')]" + }, + "innerRoleAssignmentNameSeed": { + "value": "[parameters('roleAssignmentNameSeed')]" + } + } + } + } + ], + "outputs": { + "uamidForPostDeployment": { + "type": "string", + "value": "[resourceId('${identifier.userAssignedIdentities}', variables('name_postDeploymentScriptUserDefinedManagedIdentity'))]" + } + } +} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/resources/README.md b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/resources/README.md index 05961c0a1..afb6e6a91 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/resources/README.md +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/resources/README.md @@ -1,10 +1,15 @@ + + # What is this stuff? Content that goes into the "Marketplace" tab of the offer. See [the Marketplace documentation](https://docs.microsoft.com/en-us/azure/marketplace/cloud-partner-portal/virtual-machine/cpp-marketplace-tab) for details. -When submitting the offer, use content from [https://github.com/wls-eng/arm-oraclelinux-wls/tree/master/arm-oraclelinux-wls/src/main/resources](this directory), but apply the changes in this file on top. +When submitting the offer, use content from [https://github.com/oracle/weblogic-azure/tree/main/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources](this directory), but apply the changes in this file on top. ## Offer Settings @@ -18,7 +23,7 @@ oracle Name -Oracle WebLogic Server 12.2.1.3 Cluster +Oracle WebLogic Server Cluster ## SKU Details @@ -28,7 +33,7 @@ SKU ID Title -Oracle WebLogic Server 12.2.1.3 Cluster +Oracle WebLogic Server Cluster Summary @@ -36,7 +41,7 @@ Provisions an n-node Oracle WebLogic Server Cluster Description -Provisions an n-node Oracle WebLogic Server cluster on Oracle Linux 7.6 +Provisions an n-node Oracle WebLogic Server cluster on Oracle Linux 9.1, 8.7 and 7.6 SKU Type @@ -54,7 +59,7 @@ No Title -Oracle WebLogic Server 12.2.1.3 Cluster +Oracle WebLogic Server Cluster Summary @@ -62,11 +67,11 @@ Provisions an n-node Oracle WebLogic Server Cluster Long Summary -Provisions an n-node Oracle WebLogic Server cluster on Oracle Linux 7.6 +Provisions an n-node Oracle WebLogic Server cluster on Oracle Linux 9, Oracle Linux 8 and RHEL 8. Description -[description.html](https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/master/arm-oraclelinux-wls/src/main/resources/description.html) +[description.html](https://raw.githubusercontent.com/oracle/weblogic-azure/main/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/description.html) Offer available to Microsoft CSP Reseller channel? * diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/aadIntegration.sh b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/aadIntegration.sh deleted file mode 100644 index f0ef3f737..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/aadIntegration.sh +++ /dev/null @@ -1,492 +0,0 @@ -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# Description -# This script is to configure AAD for WebLogic cluster domain. - - -#Function to output message to StdErr -function echo_stderr() -{ - echo "$@" >&2 -} - -#Function to display usage message -function usage() -{ - echo_stderr "./aadIntegration.sh <<< \"\"" -} - -function validateInput() -{ - if [[ -z "$wlsUserName" || -z "$wlsPassword" ]] - then - echo_stderr "wlsUserName or wlsPassword is required. " - exit 1 - fi - - if [ -z "$wlsDomainName" ]; - then - echo_stderr "wlsDomainName is required. " - fi - - if [ -z "$adProviderName" ]; - then - echo_stderr "adProviderName is required. " - fi - - if [ -z "$adPrincipal" ]; - then - echo_stderr "adPrincipal is required. " - fi - - if [ -z "$adPassword" ]; - then - echo_stderr "adPassword is required. " - fi - - if [ -z "$adServerHost" ]; - then - echo_stderr "adServerHost is required. " - fi - - if [ -z "$adServerPort" ]; - then - echo_stderr "adServerPort is required. " - fi - - if [ -z "$adGroupBaseDN" ]; - then - echo_stderr "adGroupBaseDN is required. " - fi - - if [ -z "$adUserBaseDN" ]; - then - echo_stderr "adUserBaseDN is required. " - fi - - if [ -z "$oracleHome" ]; - then - echo_stderr "oracleHome is required. " - fi - - if [ -z "$wlsAdminHost" ]; - then - echo_stderr "wlsAdminHost is required. " - fi - - if [ -z "$wlsAdminPort" ]; - then - echo_stderr "wlsAdminPort is required. " - fi - - if [ -z "$wlsADSSLCer" ]; - then - echo_stderr "wlsADSSLCer is required. " - fi - - if [ -z "$wlsLDAPPublicIP" ]; - then - echo_stderr "wlsLDAPPublicIP is required. " - fi - - if [ -z "$wlsDomainPath" ]; - then - echo_stderr "wlsDomainPath is required. " - fi - - if [ -z "$wlsAdminServerName" ]; - then - echo_stderr "wlsAdminServerName is required. " - fi - - if [ -z "$wlsDomainPath" ]; - then - echo_stderr "wlsDomainPath is required. " - fi - - if [ -z "$vmIndex" ]; - then - echo_stderr "vmIndex is required. " - fi - - if [ "${isCustomSSLEnabled,,}" != "true" ]; - then - echo_stderr "Custom SSL value is not provided. Defaulting to false" - isCustomSSLEnabled="false" - else - if [ -z "$customTrustKeyStorePassPhrase" ]; - then - echo "customTrustKeyStorePassPhrase is required " - exit 1 - fi - fi -} - -function createAADProvider_model() -{ - cat <${SCRIPT_PATH}/configure-active-directory.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') -try: - edit() - startEdit() - # Configure DefaultAuthenticator. - cd('/SecurityConfiguration/' + '${wlsDomainName}' + '/Realms/myrealm/AuthenticationProviders/DefaultAuthenticator') - cmo.setControlFlag('SUFFICIENT') - - # Configure Active Directory. - cd('/SecurityConfiguration/' + '${wlsDomainName}' + '/Realms/myrealm') - cmo.createAuthenticationProvider('${adProviderName}', 'weblogic.security.providers.authentication.ActiveDirectoryAuthenticator') - - cd('/SecurityConfiguration/' + '${wlsDomainName}' + '/Realms/myrealm/AuthenticationProviders/' + '${adProviderName}') - cmo.setControlFlag('OPTIONAL') - - cd('/SecurityConfiguration/' + '${wlsDomainName}' + '/Realms/myrealm') - set('AuthenticationProviders',jarray.array([ObjectName('Security:Name=myrealm' + '${adProviderName}'), - ObjectName('Security:Name=myrealmDefaultAuthenticator'), - ObjectName('Security:Name=myrealmDefaultIdentityAsserter')], ObjectName)) - - - cd('/SecurityConfiguration/' + '${wlsDomainName}' + '/Realms/myrealm/AuthenticationProviders/' + '${adProviderName}') - cmo.setControlFlag('SUFFICIENT') - cmo.setUserNameAttribute('${LDAP_USER_NAME}') - cmo.setUserFromNameFilter('${LDAP_USER_FROM_NAME_FILTER}') - cmo.setPrincipal('${adPrincipal}') - cmo.setHost('${adServerHost}') - set('Credential', '${adPassword}') - cmo.setGroupBaseDN('${adGroupBaseDN}') - cmo.setUserBaseDN('${adUserBaseDN}') - cmo.setPort(int('${adServerPort}')) - cmo.setSSLEnabled(true) - - # for performance tuning - cmo.setMaxGroupMembershipSearchLevel(1) - cmo.setGroupMembershipSearching('limited') - cmo.setUseTokenGroupsForGroupMembershipLookup(true) - cmo.setResultsTimeLimit(300) - cmo.setConnectionRetryLimit(5) - cmo.setConnectTimeout(120) - cmo.setCacheTTL(300) - cmo.setConnectionPoolSize(60) - cmo.setCacheSize(4000) - cmo.setGroupHierarchyCacheTTL(300) - cmo.setEnableSIDtoGroupLookupCaching(true) - - save() - activate() -except: - stopEdit('y') - sys.exit(1) - -disconnect() -sys.exit(0) -EOF -} - -function createSSL_model() -{ - cat <${SCRIPT_PATH}/configure-ssl.py -# Connect to the AdminServer. -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') -try: - edit() - startEdit() - servers=cmo.getServers() - for server in servers: - path="/Servers/"+server.getName()+"/SSL/"+server.getName() - print "ignore host name verification in " + server.getName() - cd(path) - cmo.setHostnameVerificationIgnored(true) -EOF - - . $oracleHome/oracle_common/common/bin/setWlstEnv.sh - ${JAVA_HOME}/bin/java -version 2>&1 | grep -e "1[.]8[.][0-9]*_" > /dev/null - javaStatus=$? - if [ "${javaStatus}" == "0" ]; then - cat <>${SCRIPT_PATH}/configure-ssl.py - if(server.getName() == '$wlsAdminServerName'): - continue - print "Enable TLSv1.2 in " + server.getName() - cd('/Servers/'+server.getName()+'//ServerStart/'+server.getName()) - arguments = cmo.getArguments() - arguments = arguments + ' ' + '${JAVA_OPTIONS_TLS_V12}' - cmo.setArguments(arguments) -EOF - fi - cat <>${SCRIPT_PATH}/configure-ssl.py - save() - activate() -except: - stopEdit('y') - sys.exit(1) - -disconnect() -sys.exit(0) -EOF -} - -function mapLDAPHostWithPublicIP() -{ - echo "map LDAP host with pubilc IP" - - # remove existing ip address for the same host - sudo sed -i '/${adServerHost}/d' /etc/hosts - sudo echo "${wlsLDAPPublicIP} ${adServerHost}" >> /etc/hosts -} - -function parseLDAPCertificate() -{ - echo "create key store" - cer_begin=0 - cer_size=${#wlsADSSLCer} - cer_line_len=64 - mkdir ${SCRIPT_PWD}/security - touch ${SCRIPT_PWD}/security/AzureADLDAPCerBase64String.txt - while [ ${cer_begin} -lt ${cer_size} ] - do - cer_sub=${wlsADSSLCer:$cer_begin:$cer_line_len} - echo ${cer_sub} >> ${SCRIPT_PWD}/security/AzureADLDAPCerBase64String.txt - cer_begin=$((cer_begin+64)) - done - - openssl base64 -d -in ${SCRIPT_PWD}/security/AzureADLDAPCerBase64String.txt -out ${SCRIPT_PWD}/security/AzureADTrust.cer - addsCertificate=${SCRIPT_PWD}/security/AzureADTrust.cer -} - -function importAADCertificate() -{ - # import the key to java security - . $oracleHome/oracle_common/common/bin/setWlstEnv.sh - # For AAD failure: exception happens when importing certificate to JDK 11.0.7 - # ISSUE: https://github.com/wls-eng/arm-oraclelinux-wls/issues/109 - # JRE was removed since JDK 11. - java_version=$(java -version 2>&1 | sed -n ';s/.* version "\(.*\)\.\(.*\)\..*"/\1\2/p;') - if [ ${java_version:0:3} -ge 110 ]; - then - java_cacerts_path=${JAVA_HOME}/lib/security/cacerts - else - java_cacerts_path=${JAVA_HOME}/jre/lib/security/cacerts - fi - - # remove existing certificate. - queryAADTrust=$(${JAVA_HOME}/bin/keytool -list -keystore ${java_cacerts_path} -storepass changeit | grep "aadtrust") - if [ -n "${queryAADTrust}" ]; - then - sudo ${JAVA_HOME}/bin/keytool -delete -alias aadtrust -keystore ${java_cacerts_path} -storepass changeit - fi - - sudo ${JAVA_HOME}/bin/keytool -noprompt -import -alias aadtrust -file ${addsCertificate} -keystore ${java_cacerts_path} -storepass changeit - -} - -function importAADCertificateIntoWLSCustomTrustKeyStore() -{ - if [ "${isCustomSSLEnabled,,}" == "true" ]; - then - # set java home - . $oracleHome/oracle_common/common/bin/setWlstEnv.sh - - #validate Trust keystore - sudo ${JAVA_HOME}/bin/keytool -list -v -keystore ${DOMAIN_PATH}/${wlsDomainName}/keystores/trust.keystore -storepass ${customTrustKeyStorePassPhrase} -storetype ${customTrustKeyStoreType} | grep 'Entry type:' | grep 'trustedCertEntry' - - if [[ $? != 0 ]]; then - echo "Error : Trust Keystore Validation Failed !!" - exit 1 - fi - - # For SSL enabled causes AAD failure #225 - # ISSUE: https://github.com/wls-eng/arm-oraclelinux-wls/issues/225 - - echo "Importing AAD Certificate into WLS Custom Trust Key Store: " - - sudo ${JAVA_HOME}/bin/keytool -noprompt -import -trustcacerts -keystore ${DOMAIN_PATH}/${wlsDomainName}/keystores/trust.keystore -storepass ${customTrustKeyStorePassPhrase} -alias aadtrust -file ${addsCertificate} -storetype ${customTrustKeyStoreType} - else - echo "customSSL not enabled. Not required to configure AAD for WebLogic Custom SSL" - fi -} - -function configureSSL() -{ - echo "configure ladp ssl" - sudo chown -R ${USER_ORACLE}:${GROUP_ORACLE} ${SCRIPT_PATH} - runuser -l ${USER_ORACLE} -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST ${SCRIPT_PATH}/configure-ssl.py" - - errorCode=$? - if [ $errorCode -eq 1 ] - then - echo "Exception occurs during SSL configuration, please check." - exit 1 - fi -} - -function configureAzureActiveDirectory() -{ - echo "create Azure Active Directory provider" - sudo chown -R ${USER_ORACLE}:${GROUP_ORACLE} ${SCRIPT_PATH} - runuser -l ${USER_ORACLE} -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST ${SCRIPT_PATH}/configure-active-directory.py" - - errorCode=$? - if [ $errorCode -eq 1 ] - then - echo "Exception occurs during Azure Active Directory configuration, please check." - exit 1 - fi -} - -function restartAdminServerService() -{ - echo "Restart weblogic admin server service" - sudo systemctl stop wls_admin - sudo systemctl start wls_admin -} - -function restartManagedServers() -{ - echo "Restart managed servers" - cat <${SCRIPT_PWD}/restart-managedServer.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') -servers=cmo.getServers() -domainRuntime() -print "Restart the servers which are in RUNNING status" -for server in servers: - bean="/ServerLifeCycleRuntimes/"+server.getName() - serverbean=getMBean(bean) - if (serverbean.getState() in ("RUNNING")) and (server.getName() != '${wlsAdminServerName}'): - try: - print "Stop the Server ",server.getName() - shutdown(server.getName(),server.getType(),ignoreSessions='true',force='true') - print "Start the Server ",server.getName() - start(server.getName(),server.getType()) - except: - print "Failed restarting managed server ", server.getName() - dumpStack() -serverConfig() -disconnect() -EOF - . $oracleHome/oracle_common/common/bin/setWlstEnv.sh - java $WLST_ARGS weblogic.WLST ${SCRIPT_PWD}/restart-managedServer.py - - if [[ $? != 0 ]]; then - echo "Error : Fail to restart managed server to sync up aad configuration." - exit 1 - fi -} - -#This function to check admin server status -function wait_for_admin() -{ - #check admin server status - count=1 - CHECK_URL="http://$wlsAdminURL/weblogic/ready" - status=`curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}` - echo "Check admin server status" - while [[ "$status" != "200" ]] - do - echo "." - count=$((count+1)) - if [ $count -le 30 ]; - then - sleep 1m - else - echo "Error : Maximum attempts exceeded while checking admin server status" - exit 1 - fi - status=`curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}` - if [ "$status" == "200" ]; - then - echo "WebLogic Server is running..." - break - fi - done -} - -function cleanup() -{ - echo "Cleaning up temporary files..." - rm -f -r ${SCRIPT_PATH} - rm -rf ${SCRIPT_PWD}/security/* - echo "Cleanup completed." -} - -function enableTLSv12onJDK8() -{ - if ! grep -q "${STRING_ENABLE_TLSV12}" ${wlsDomainPath}/bin/setDomainEnv.sh; then - cat <>${wlsDomainPath}/bin/setDomainEnv.sh -# Append -Djdk.tls.client.protocols to JAVA_OPTIONS in jdk8 -# Enable TLSv1.2 -\${JAVA_HOME}/bin/java -version 2>&1 | grep -e "1[.]8[.][0-9]*_" > /dev/null -javaStatus=$? - -if [[ "\${javaStatus}" = "0" && "\${JAVA_OPTIONS}" != *"${JAVA_OPTIONS_TLS_V12}"* ]]; then - JAVA_OPTIONS="\${JAVA_OPTIONS} ${JAVA_OPTIONS_TLS_V12}" - export JAVA_OPTIONS -fi -EOF -fi -} - -function createTempFolder() -{ - SCRIPT_PATH="/u01/tmp" - sudo rm -f -r ${SCRIPT_PATH} - sudo mkdir ${SCRIPT_PATH} - sudo rm -rf $SCRIPT_PATH/* -} - -#main - -#read arguments from stdin -read wlsUserName wlsPassword wlsDomainName adProviderName adServerHost adServerPort adPrincipal adPassword adGroupBaseDN adUserBaseDN oracleHome wlsAdminHost wlsAdminPort wlsADSSLCer wlsLDAPPublicIP wlsAdminServerName wlsDomainPath isCustomSSLEnabled customTrustKeyStorePassPhrase customTrustKeyStoreType vmIndex - -isCustomSSLEnabled="${isCustomSSLEnabled,,}" - -if [ "${isCustomSSLEnabled,,}" == "true" ]; -then - customTrustKeyStorePassPhrase=$(echo "$customTrustKeyStorePassPhrase" | base64 --decode) - customTrustKeyStoreType=$(echo "$customTrustKeyStoreType" | base64 --decode) -fi - -wlsAdminURL=$wlsAdminHost:$wlsAdminPort - -LDAP_USER_NAME='sAMAccountName' -LDAP_USER_FROM_NAME_FILTER='(&(sAMAccountName=%u)(objectclass=user))' -JAVA_OPTIONS_TLS_V12="-Djdk.tls.client.protocols=TLSv1.2" -STRING_ENABLE_TLSV12="Append -Djdk.tls.client.protocols to JAVA_OPTIONS in jdk8" -SCRIPT_PWD=`pwd` -USER_ORACLE="oracle" -GROUP_ORACLE="oracle" -DOMAIN_PATH="/u01/domains" - - -if [ $vmIndex -eq 0 ]; -then - createTempFolder - echo "check status of admin server" - wait_for_admin - - echo "start to configure Azure Active Directory" - enableTLSv12onJDK8 - createAADProvider_model - createSSL_model - mapLDAPHostWithPublicIP - parseLDAPCertificate - importAADCertificate - importAADCertificateIntoWLSCustomTrustKeyStore - configureSSL - configureAzureActiveDirectory - restartAdminServerService - - echo "Waiting for admin server to be available" - wait_for_admin - echo "Weblogic admin server is up and running" - - restartManagedServers - cleanup -else - cleanup - mapLDAPHostWithPublicIP - parseLDAPCertificate - importAADCertificate - importAADCertificateIntoWLSCustomTrustKeyStore - cleanup -fi - diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/datasourceConfig-mysql.sh b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/datasourceConfig-mysql.sh new file mode 100644 index 000000000..a657062a3 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/datasourceConfig-mysql.sh @@ -0,0 +1,192 @@ +# Copyright (c) 2021, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +# Description +# This script is to configure datasource at WebLogic cluster domain. + +#Function to output message to StdErr +function echo_stderr () +{ + echo "$@" >&2 +} + +#Function to display usage message +function usage() +{ + echo_stderr "./configDatasource.sh <<< \"\"" +} + +function validateInput() +{ + # parse base64 string + wlsShibboleth=$(echo "${wlsShibboleth}" | base64 -d) + jdbcDataSourceName=$(echo "${jdbcDataSourceName}" | base64 -d) + dsConnectionURL=$(echo "${dsConnectionURL}" | base64 -d) + dsPassword=$(echo "${dsPassword}" | base64 -d) + + if [ -z "$oracleHome" ]; + then + echo _stderr "Please provide oracleHome" + exit 1 + fi + + if [ -z "$wlsAdminHost" ]; + then + echo _stderr "Please provide WeblogicServer hostname" + exit 1 + fi + + if [ -z "$wlsAdminPort" ]; + then + echo _stderr "Please provide Weblogic admin port" + exit 1 + fi + + if [ -z "$wlsUserName" ]; + then + echo _stderr "Please provide Weblogic username" + exit 1 + fi + + if [ -z "$wlsShibboleth" ]; + then + echo _stderr "Please provide Weblogic password" + exit 1 + fi + + if [ -z "$jdbcDataSourceName" ]; + then + echo _stderr "Please provide JDBC datasource name to be configured" + exit 1 + fi + + if [ -z "$dsConnectionURL" ]; + then + echo _stderr "Please provide Azure database of MySQL URL in the format 'jdbc:oracle:thin:@:/'" + exit 1 + fi + + if [ -z "$dsUser" ]; + then + echo _stderr "Please provide Azure database of MySQL user name" + exit 1 + fi + + if [ -z "$dsPassword" ]; + then + echo _stderr "Please provide Azure database of MySQL password" + exit 1 + fi + + if [ -z "$dbGlobalTranPro" ]; + then + echo _stderr "Please provide Global transactions protocol" + exit 1 + fi + + if [ -z "${enablePswlessConnection}" ]; + then + echo _stderr "Please provide enablePswlessConnection to identity if enabling passwordless connection." + exit 1 + fi + + if [ -z "$wlsClusterName" ]; + then + echo _stderr "Please provide Weblogic target cluster name" + exit 1 + fi + + # reset password + if [[ "${enablePswlessConnection,,}" == "true" ]]; then + dsPassword="" + fi +} + +function createJDBCSource_model() +{ + local driverName="com.mysql.jdbc.Driver" + if [[ "${enablePswlessConnection,,}" == "true" ]]; then + driverName="com.mysql.cj.jdbc.Driver" + fi + + echo "Creating JDBC data source with name $jdbcDataSourceName" + cat <${scriptPath}/create_datasource.py +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') +edit("$hostName") +startEdit() +cd('/') +try: + cmo.createJDBCSystemResource('$jdbcDataSourceName') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName') + cmo.setName('$jdbcDataSourceName') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDataSourceParams/$jdbcDataSourceName') + set('JNDINames',jarray.array([String('$jdbcDataSourceName')], String)) + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName') + cmo.setDatasourceType('GENERIC') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDriverParams/$jdbcDataSourceName') + cmo.setUrl('$dsConnectionURL') + cmo.setDriverName('$driverName') + cmo.setPassword('$dsPassword') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCConnectionPoolParams/$jdbcDataSourceName') + cmo.setTestTableName('SQL ISVALID\r\n\r\n\r\n\r\n') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDriverParams/$jdbcDataSourceName/Properties/$jdbcDataSourceName') + cmo.createProperty('user') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDriverParams/$jdbcDataSourceName/Properties/$jdbcDataSourceName/Properties/user') + cmo.setValue('$dsUser') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDataSourceParams/$jdbcDataSourceName') + cmo.setGlobalTransactionsProtocol('${dbGlobalTranPro}') + cd('/JDBCSystemResources/$jdbcDataSourceName') + set('Targets',jarray.array([ObjectName('com.bea:Name=$wlsClusterName,Type=Cluster')], ObjectName)) + save() + resolve() + activate() +except Exception, e: + e.printStackTrace() + dumpStack() + undo('true',defaultAnswer='y') + cancelEdit('y') + destroyEditSession("$hostName",force = true) + raise("$jdbcDataSourceName configuration failed") +destroyEditSession("$hostName",force = true) +disconnect() +EOF +} + +function createTempFolder() +{ + scriptPath="/u01/tmp" + sudo rm -f -r ${scriptPath} + sudo mkdir ${scriptPath} + sudo rm -rf $scriptPath/* +} + +#main + +#read arguments from stdin +read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsShibboleth jdbcDataSourceName dsConnectionURL dsUser dsPassword dbGlobalTranPro enablePswlessConnection wlsClusterName + +if [ -z "$wlsClusterName" ]; +then + wlsClusterName="cluster1" +fi + +wlsAdminURL=$wlsAdminHost:$wlsAdminPort +hostName=`hostname` + +createTempFolder +validateInput +createJDBCSource_model + +sudo chown -R oracle:oracle ${scriptPath} +runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST ${scriptPath}/create_datasource.py" + +errorCode=$? +if [ $errorCode -eq 1 ] +then + echo "Exception occurs during DB configuration, please check." + exit 1 +fi + +echo "Cleaning up temporary files..." +rm -f -r ${scriptPath} + + diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/datasourceConfig-oracle.sh b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/datasourceConfig-oracle.sh index 09c58d59c..a73f8204c 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/datasourceConfig-oracle.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/datasourceConfig-oracle.sh @@ -17,6 +17,11 @@ function usage() function validateInput() { + # parse base64 string + wlsShibboleth=$(echo "${wlsShibboleth}" | base64 -d) + jdbcDataSourceName=$(echo "${jdbcDataSourceName}" | base64 -d) + dsConnectionURL=$(echo "${dsConnectionURL}" | base64 -d) + dsPassword=$(echo "${dsPassword}" | base64 -d) if [ -z "$oracleHome" ]; then @@ -42,7 +47,7 @@ function validateInput() exit 1 fi - if [ -z "$wlsPassword" ]; + if [ -z "$wlsShibboleth" ]; then echo _stderr "Please provide Weblogic password" exit 1 @@ -72,19 +77,35 @@ function validateInput() exit 1 fi + if [ -z "$dbGlobalTranPro" ]; + then + echo _stderr "Please provide Global transactions protocol" + exit 1 + fi + if [ -z "$wlsClusterName" ]; then echo _stderr "Please provide Weblogic target cluster name" exit 1 fi + if [ -z "${enablePswlessConnection}" ]; + then + echo _stderr "Please provide enablePswlessConnection to identity if enabling passwordless connection." + exit 1 + fi + + # reset password + if [[ "${enablePswlessConnection,,}" == "true" ]]; then + dsPassword="" + fi } function createJDBCSource_model() { echo "Creating JDBC data source with name $jdbcDataSourceName" cat <${scriptPath}/create_datasource.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') edit("$hostName") startEdit() cd('/') @@ -107,7 +128,7 @@ try: cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDriverParams/$jdbcDataSourceName/Properties/$jdbcDataSourceName/Properties/user') cmo.setValue('$dsUser') cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDataSourceParams/$jdbcDataSourceName') - cmo.setGlobalTransactionsProtocol('EmulateTwoPhaseCommit') + cmo.setGlobalTransactionsProtocol('${dbGlobalTranPro}') cd('/JDBCSystemResources/$jdbcDataSourceName') set('Targets',jarray.array([ObjectName('com.bea:Name=$wlsClusterName,Type=Cluster')], ObjectName)) save() @@ -136,7 +157,7 @@ function createTempFolder() #main #read arguments from stdin -read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsPassword jdbcDataSourceName dsConnectionURL dsUser dsPassword wlsClusterName +read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsShibboleth jdbcDataSourceName dsConnectionURL dsUser dsPassword dbGlobalTranPro enablePswlessConnection wlsClusterName if [ -z "$wlsClusterName" ]; then diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/datasourceConfig-postgresql.sh b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/datasourceConfig-postgresql.sh index 6dea2e6d3..b349bd9aa 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/datasourceConfig-postgresql.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/datasourceConfig-postgresql.sh @@ -17,6 +17,11 @@ function usage() function validateInput() { + # parse base64 string + wlsShibboleth=$(echo "${wlsShibboleth}" | base64 -d) + jdbcDataSourceName=$(echo "${jdbcDataSourceName}" | base64 -d) + dsConnectionURL=$(echo "${dsConnectionURL}" | base64 -d) + dsPassword=$(echo "${dsPassword}" | base64 -d) if [ -z "$oracleHome" ]; then @@ -42,7 +47,7 @@ function validateInput() exit 1 fi - if [ -z "$wlsPassword" ]; + if [ -z "$wlsShibboleth" ]; then echo _stderr "Please provide Weblogic password" exit 1 @@ -72,19 +77,35 @@ function validateInput() exit 1 fi + if [ -z "$dbGlobalTranPro" ]; + then + echo _stderr "Please provide Global transactions protocol" + exit 1 + fi + if [ -z "$wlsClusterName" ]; then echo _stderr "Please provide Weblogic target cluster name" exit 1 fi + if [ -z "${enablePswlessConnection}" ]; + then + echo _stderr "Please provide enablePswlessConnection to identity if enabling passwordless connection." + exit 1 + fi + + # reset password + if [[ "${enablePswlessConnection,,}" == "true" ]]; then + dsPassword="" + fi } function createJDBCSource_model() { echo "Creating JDBC data source with name $jdbcDataSourceName" cat <${scriptPath}/create_datasource.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') edit("$hostName") startEdit() cd('/') @@ -107,7 +128,7 @@ try: cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDriverParams/$jdbcDataSourceName/Properties/$jdbcDataSourceName/Properties/user') cmo.setValue('$dsUser') cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDataSourceParams/$jdbcDataSourceName') - cmo.setGlobalTransactionsProtocol('EmulateTwoPhaseCommit') + cmo.setGlobalTransactionsProtocol('${dbGlobalTranPro}') cd('/JDBCSystemResources/$jdbcDataSourceName') set('Targets',jarray.array([ObjectName('com.bea:Name=$wlsClusterName,Type=Cluster')], ObjectName)) save() @@ -136,7 +157,7 @@ function createTempFolder() #main #read arguments from stdin -read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsPassword jdbcDataSourceName dsConnectionURL dsUser dsPassword wlsClusterName +read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsShibboleth jdbcDataSourceName dsConnectionURL dsUser dsPassword dbGlobalTranPro enablePswlessConnection wlsClusterName if [ -z "$wlsClusterName" ]; then diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/datasourceConfig-sqlserver.sh b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/datasourceConfig-sqlserver.sh index 2e62ec841..b30e143ed 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/datasourceConfig-sqlserver.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/datasourceConfig-sqlserver.sh @@ -17,6 +17,11 @@ function usage() function validateInput() { + # parse base64 string + wlsShibboleth=$(echo "${wlsShibboleth}" | base64 -d) + jdbcDataSourceName=$(echo "${jdbcDataSourceName}" | base64 -d) + dsConnectionURL=$(echo "${dsConnectionURL}" | base64 -d) + dsPassword=$(echo "${dsPassword}" | base64 -d) if [ -z "$oracleHome" ]; then @@ -42,7 +47,7 @@ function validateInput() exit 1 fi - if [ -z "$wlsPassword" ]; + if [ -z "$wlsShibboleth" ]; then echo _stderr "Please provide Weblogic password" exit 1 @@ -72,19 +77,36 @@ function validateInput() exit 1 fi + if [ -z "$dbGlobalTranPro" ]; + then + echo _stderr "Please provide Global transactions protocol" + exit 1 + fi + if [ -z "$wlsClusterName" ]; then echo _stderr "Please provide Weblogic target cluster name" exit 1 fi + if [ -z "${enablePswlessConnection}" ]; + then + echo _stderr "Please provide enablePswlessConnection to identity if enabling passwordless connection." + exit 1 + fi + + # reset password and user + if [[ "${enablePswlessConnection,,}" == "true" ]]; then + dsPassword="" + dsUser="" + fi } function createJDBCSource_model() { echo "Creating JDBC data source with name $jdbcDataSourceName" cat <${scriptPath}/create_datasource.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') edit("$hostName") startEdit() cd('/') @@ -107,7 +129,7 @@ try: cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDriverParams/$jdbcDataSourceName/Properties/$jdbcDataSourceName/Properties/user') cmo.setValue('$dsUser') cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDataSourceParams/$jdbcDataSourceName') - cmo.setGlobalTransactionsProtocol('EmulateTwoPhaseCommit') + cmo.setGlobalTransactionsProtocol('${dbGlobalTranPro}') cd('/JDBCSystemResources/$jdbcDataSourceName') set('Targets',jarray.array([ObjectName('com.bea:Name=$wlsClusterName,Type=Cluster')], ObjectName)) save() @@ -136,7 +158,7 @@ function createTempFolder() #main #read arguments from stdin -read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsPassword jdbcDataSourceName dsConnectionURL dsUser dsPassword wlsClusterName +read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsShibboleth jdbcDataSourceName dsConnectionURL dsUser dsPassword dbGlobalTranPro enablePswlessConnection wlsClusterName if [ -z "$wlsClusterName" ]; then diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/elkIntegration.sh b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/elkIntegration.sh deleted file mode 100644 index 1886abe37..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/elkIntegration.sh +++ /dev/null @@ -1,752 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# Description -# This script is to configure ELK integration with WebLogic cluster domain. - -#Function to output message to StdErr -function echo_stderr() { - echo "$@" >&2 -} - -#Function to display usage message -function usage() { - echo_stderr "./elkIntegration.sh <<< \"\"" -} - -function validate_input() { - if [ -z "$oracleHome" ]; then - echo_stderr "oracleHome is required. " - exit 1 - fi - - if [ -z "$wlsAdminURL" ]; then - echo_stderr "wlsAdminURL is required. " - exit 1 - fi - - if [[ -z "$wlsUserName" || -z "$wlsPassword" ]]; then - echo_stderr "wlsUserName or wlsPassword is required. " - exit 1 - fi - - if [ -z "$wlsAdminServerName" ]; then - echo_stderr "wlsAdminServerName is required. " - exit 1 - fi - - if [ -z "$elasticURI" ]; then - echo_stderr "elasticURI is required. " - exit 1 - fi - - if [[ -z "$elasticUserName" || -z "$elasticPassword" ]]; then - echo_stderr "elasticUserName or elasticPassword is required. " - exit 1 - fi - - if [ -z "$wlsDomainName" ]; then - echo_stderr "wlsDomainName is required. " - exit 1 - fi - - if [ -z "$wlsDomainPath" ]; then - echo_stderr "wlsDomainPath is required. " - exit 1 - fi - - if [ -z "$index" ]; then - echo_stderr "index is required. " - exit 1 - fi - - if [ -z "$logsToIntegrate" ]; then - echo_stderr "logsToIntegrate is required. " - exit 1 - fi - - if [ -z "$logIndex" ]; then - echo_stderr "logIndex is required. " - exit 1 - fi - - if [ -z "$managedServerPrefix" ]; then - echo_stderr "managedServerPrefix is required. " - exit 1 - fi -} - -# Set access log with format: date time time-taken bytes c-ip s-ip c-dns s-dns cs-method cs-uri sc-status sc-comment ctx-ecid -# Redirect stdout logging enabled: true -# Redirect stderr logging enabled: true -# Stack Traces to stdout: true -function create_wls_log_model() { - cat <${SCRIPT_PATH}/configure-wls-log.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') -servers=cmo.getServers() - -try: - edit("$hostName") - startEdit() - for server in servers: - bean="/ServerLifeCycleRuntimes/"+server.getName() - cd('/Servers/'+server.getName()+'/WebServer/'+server.getName()+'/WebServerLog/'+server.getName()) - cmo.setLogFileFormat('extended') - cmo.setELFFields('date time time-taken bytes c-ip s-ip c-dns s-dns cs-method cs-uri sc-status sc-comment ctx-ecid ctx-rid') - - cd('/Servers/'+server.getName()+'/Log/'+server.getName()) - cmo.setRedirectStderrToServerLogEnabled(true) - cmo.setRedirectStdoutToServerLogEnabled(true) - cmo.setStdoutLogStack(true) - - save() - resolve() - activate() -except: - stopEdit('y') - sys.exit(1) - -destroyEditSession("$hostName",force = true) -disconnect() -EOF -} - -# Remove existing Logstash -function remove_logstash() { - sudo systemctl status logstash - if [ $? -ne 0 ]; then - sudo systemctl stop logstash - fi - - sudo yum remove -y -v logstash - if [ $? -ne 0 ]; then - echo_stderr "Fail to remove existing Logstash." - exit 1 - fi -} - -# Install Logstash -function install_logstash() { - sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch - - cat </etc/yum.repos.d/logstash.repo -[logstash-7.x] -name=Elastic repository for 7.x packages -baseurl=https://artifacts.elastic.co/packages/7.x/yum -gpgcheck=1 -gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch -enabled=1 -autorefresh=1 -type=rpm-md -EOF - sudo yum install -y -v logstash - if [ ! -d "/usr/share/logstash" ]; then - echo_stderr "Fail to install Logstash." - exit 1 - fi -} - -# Start Logstash service -function start_logstash() { - sudo systemctl enable logstash - sudo systemctl daemon-reload - - #Start logstash - attempt=1 - while [[ $attempt -lt 4 ]]; do - echo "Starting logstash service attempt $attempt" - sudo systemctl start logstash - attempt=$(expr $attempt + 1) - sudo systemctl status logstash | grep running - if [[ $? == 0 ]]; then - echo "logstash service started successfully" - break - fi - sleep 1m - done -} - -# Configure Logstash: -# * grok patterns -> /etc/logstash/patterns/weblogic-logstash-patterns.txt -# * conf files -> /etc/logstash/conf.d -# * JAVA_HOME -> /etc/logstash/startup.options -# * create logstash start up -# Examples for patterns: -# * ACCESSDATE -# * parse date of access -# * 2020-09-01 -# * DBDATETIME -# * parse data source datetime -# * Tue Sep 01 05:05:41 UTC 2020 -# * DSIDORTIMESTAMP -# * parse data source dynamic fields: id | timestamp, one of them exists. -# * timestamp: Tue Sep 01 05:05:41 UTC 2020 -# * id: 64 -# * DSPARTITION -# * parse partition info. -# * [partition-name: DOMAIN] [partition-id: 0] -# * [partition-id: 0] [partition-name: DOMAIN] -# * DSWEBLOGICMESSAGE -# * parse data source user id or error messsage. -# * error: Java stack trace -# * user id: -# * WEBLOGICDIAGMESSAGE -# * parse domain log message. -# * e.g. Java stack trace -# * e.g. Self-tuning thread pool contains 0 running threads, 2 idle threads, and 13 standby threads -# * WEBLOGICDOMAINDATE -# * parse domain|server log datetime. -# * from wls 14: Sep 1, 2020, 5:41:51,040 AM Coordinated Universal Time -# * from wls 12: Sep 1, 2020 5:41:51,040 AM Coordinated Universal Time -# * WEBLOGICLOGPARTITION -# * parse partition info in domain log. -# * [severity-value: 64] -# * [severity-value: 64] [rid: 0] -# * [severity-value: 64] [partition-id: 0] [partition-name: DOMAIN ] -# * [severity-value: 64] [rid: 0] [partition-id: 0] [partition-name: DOMAIN ] -# * WEBLOGICSERVERLOGPARTITION -# * parse partition info in server log. -# * [severity-value: 64] -# * [severity-value: 64] [rid: 0] -# * [severity-value: 64] [partition-id: 0] [partition-name: DOMAIN ] -# * [severity-value: 64] [rid: 0] [partition-id: 0] [partition-name: DOMAIN ] -# * WEBLOGICSERVERRID -# * parse dynamic filed rid in server log. -# * [rid: 0] -# * WEBLOGICSERVERMESSAGE -# * parse field message in server log. -# * e.g. Java stack trace -# * e.g. Self-tuning thread pool contains 0 running threads, 2 idle threads, and 13 standby threads -# * WEBLOGICSTDDATE -# * parse field date in std log. -# * Aug 31, 2020 5:37:27,646 AM UTC -# * Aug 31, 2020 5:37:27 AM UTC -function configure_lostash() { - echo "create patterns" - rm -f -r /etc/logstash/patterns - if [ -d "/etc/logstash/patterns" ]; then - rm -f /etc/logstash/patterns/weblogic-logstash-patterns.txt - else - mkdir /etc/logstash/patterns - fi - cat </etc/logstash/patterns/weblogic-logstash-patterns.txt -ACCESSDATE ^\d{4}[./-]%{MONTHNUM}[./-]%{MONTHDAY} -DBDATETIME %{DAY} %{MONTH:db_month} %{MONTHDAY:db_day} %{HOUR:db_hour}:%{MINUTE:db_minute}:%{SECOND:db_second} %{TZ:db_tz} %{YEAR:db_year} -DSIDORTIMESTAMP (?(\b(?:[1-9][0-9]*)\b))|%{DBDATETIME:ds_timestamp} -DSPARTITION (?:\[partition-id: %{INT:ds_partitionId}\] \[partition-name: %{DATA:ds_partitionName}\]\s)|(?:\[partition-name: %{DATA:ds_partitionName}\] \[partition-id: %{INT:ds_partitionId}\]\s) -DSWEBLOGICMESSAGE (?(.|\r|\n)*)|%{GREEDYDATA:ds_user} -JAVAPACKAGE ([a-zA-Z_$][a-zA-Z\d_$]*\.)*[a-zA-Z_$][a-zA-Z\d_$]* -NODEMANAGERMESSAGE (?(.|\r|\n[^A-Za-z0-9])*)|%{GREEDYDATA:node_message} -NODEMANAGEREND (<%{WORDNOSPACES:node_domain}>\s<%{WORDNOSPACES:node_server}>\s<%{NODEMANAGERMESSAGE}>)|(<%{GREEDYDATA:node_messageType}>\s<%{NODEMANAGERMESSAGE}>)|<%{NODEMANAGERMESSAGE}> -WEBLOGICDIAGMESSAGE (?(.|\r|\n)*)|%{GREEDYDATA:diag_message} -WEBLOGICDOMAINDATE %{MONTH:tmp_month} %{MONTHDAY:tmp_day}, %{YEAR:tmp_year},? %{HOUR:tmp_hour}:%{MINUTE:tmp_min}:%{SECOND:tmp_second},(?([0-9]{3})) (?(AM|PM)) -WEBLOGICLOGPARTITION (?:\s\[rid: %{DATA:diag_rid}\] \[partition-id: %{INT:diag_partitionId}\] \[partition-name: %{DATA:diag_partitionName}\]\s)|(?:\s\[partition-id: %{INT:diag_partitionId}\] \[partition-name: %{DATA:diag_partitionName}\]\s)|(?:\s\[rid: %{DATA:diag_rid}\]\s)|(\s) -WEBLOGICSERVERLOGPARTITION (?:\s\[rid: %{DATA:log_rid}\] \[partition-id: %{INT:log_partitionId}\] \[partition-name: %{DATA:log_partitionName}\]\s)|(?:\s\[partition-id: %{INT:log_partitionId}\] \[partition-name: %{DATA:log_partitionName}\]\s)|(?:\s\[rid: %{DATA:log_rid}\]\s)|(\s) -WEBLOGICSERVERRID (?:\s\[rid: %{WORDNOSPACES:log_rid}\]\s)|(\s) -WEBLOGICSERVERMESSAGE (?(.|\r|\n)*)|%{GREEDYDATA:log_message} -WEBLOGICSTDDATE %{MONTH:tmp_month} %{MONTHDAY:tmp_day}, %{YEAR:tmp_year},? %{HOUR:tmp_hour}:%{MINUTE:tmp_min}:%{SECOND:tmp_second} (?(AM|PM)) -WEBLOGICSTDMESSAGE (?(.|\r|\n[^A-Za-z0-9])*)|%{GREEDYDATA:out_message} -WEBLOGICSTDDYNAMICID (<%{WORDNOSPACES:out_messageId}>\s<%{WEBLOGICSTDMESSAGE}>)|<%{WEBLOGICSTDMESSAGE}> -WORDNOSPACES [^ ]* -WORDNOBRACKET [^\]]* -WORDWITHSPACE (\b\w+\b|\s)* -EOF - - if [ $index -eq 0 ]; then - serverName=$wlsAdminServerName - else - serverName="${managedServerPrefix}${index}" - fi - wlsLogPath="${wlsDomainPath}/servers/${serverName}/logs" - privateIP=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/') - - rm -f /etc/logstash/conf.d/weblogic-logs.conf - cat </etc/logstash/conf.d/weblogic-logs.conf -input { -EOF - - if [[ -n $(echo ${logsToIntegrate} | grep "HTTPAccessLog") ]]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { - path => "${wlsLogPath}/access.log" - start_position => beginning - } -EOF - fi - - if [[ -n $(echo ${logsToIntegrate} | grep "ServerLog") ]]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { - path => "${wlsLogPath}/${serverName}.log" - codec => multiline { - pattern => "^####" - negate => true - what => "previous" - } - start_position => beginning - } -EOF - fi - - if [[ -n $(echo ${logsToIntegrate} | grep "DomainLog") ]]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { - path => "${wlsLogPath}/${wlsDomainName}.log" - codec => multiline { - pattern => "^####" - negate => true - what => "previous" - } - start_position => beginning - } -EOF - fi - - if [[ -n $(echo ${logsToIntegrate} | grep "DataSourceLog") ]]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { - path => "${wlsLogPath}/datasource.log" - codec => multiline { - pattern => "^####" - negate => true - what => "previous" - } - start_position => beginning - } -EOF - fi - - if [[ -n $(echo ${logsToIntegrate} | grep "StandardErrorAndOutput") ]]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { - path => "${wlsLogPath}/${serverName}.out" - codec => multiline { - pattern => "^<" - negate => true - what => "previous" - } - start_position => beginning - } -EOF - fi - - if [[ -n $(echo ${logsToIntegrate} | grep "NodeManagerLog") ]]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { - path => "${wlsDomainPath}/nodemanager/nodemanager.log" - codec => multiline { - pattern => "^<" - negate => true - what => "previous" - } - start_position => beginning - } -EOF - fi - - cat <>/etc/logstash/conf.d/weblogic-logs.conf -} -filter { - grok { - match => {"path" => "%{GREEDYDATA}/%{GREEDYDATA:type}"} - } - mutate { - add_field => { "internal_ip" => "${privateIP}" } - } - - if [type] == "${serverName}.log" { - mutate { replace => { type => "weblogic_server_log" } } - # match rid - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "####<%{WEBLOGICDOMAINDATE}%{SPACE}%{GREEDYDATA:log_timezone}>%{SPACE}<%{LOGLEVEL:log_severity}>%{SPACE}<%{GREEDYDATA:log_subSystem}>%{SPACE}<%{HOSTNAME:log_machine}>%{SPACE}<%{DATA:log_server}>%{SPACE}<%{DATA:log_thread}>%{SPACE}<%{DATA:log_userId}>%{SPACE}<%{DATA:log_transactionId}>%{SPACE}<%{DATA:log_contextId}>%{SPACE}<%{NUMBER:log_timestamp}>%{SPACE}<\[severity-value: %{INT:log_severityValue}\]%{WEBLOGICSERVERLOGPARTITION}>%{SPACE}<%{DATA:log_massageId}>%{SPACE}<%{WEBLOGICSERVERMESSAGE}>" ] - } - - mutate { - replace => ['log_date', '%{tmp_month} %{tmp_day}, %{tmp_year} %{tmp_hour}:%{tmp_min}:%{tmp_second},%{tmp_sss} %{tmp_aa}'] - } - - translate { - field => 'log_timezone' - destination => 'log_timezone' - fallback => '%{log_timezone}' - override => "true" - dictionary => { - "Coordinated Universal Time" => "UTC" - } - } - - date { - match => [ "log_date", "MMM dd, YYYY KK:mm:ss,SSS aa", "MMM d, YYYY KK:mm:ss,SSS aa"] - timezone => "%{log_timezone}" - target => "log_date" - } - mutate { - remove_field => [ 'log_timezone', 'tmp_month', 'tmp_day', 'tmp_year', 'tmp_hour', 'tmp_min', 'tmp_second', 'tmp_sss', 'tmp_aa'] - } - } - else if [type] == "access.log" { - # drop message starting with # - if [message] =~ /^#/ { - drop {} - } - mutate { replace => { type => "weblogic_access_log" } } - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "%{ACCESSDATE:acc_date}\s+%{TIME:acc_time}\s+%{NUMBER:time_taken}\s+%{NUMBER:bytes:int}\s+%{IP:c_ip}\s+%{HOSTPORT:s_ip}\s+%{IPORHOST:c_dns}\s+%{IPORHOST:s_dns}\s+%{WORD:cs_method}\s+%{URIPATHPARAM:cs_uri}\s+%{NUMBER:sc_status}\s+%{QUOTEDSTRING:sc-comment}\s+%{WORDNOSPACES:ctx-ecid}\s+%{WORDNOSPACES:ctx-rid}" ] - } - mutate { - replace => ['acc_timestamp', '%{acc_date} %{acc_time}'] - } - date { - match => [ "acc_timestamp" , "yyyy-MM-dd HH:mm:ss" ] - timezone => "UTC" - target => "acc_timestamp" - } - mutate { - remove_field => [ 'acc_date', 'acc_time'] - } - } - else if [type] == "${wlsDomainName}.log" { - mutate { replace => { type => "weblogic_domain_log" } } - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "####<%{WEBLOGICDOMAINDATE}%{SPACE}%{GREEDYDATA:diag_timezone}>%{SPACE}<%{LOGLEVEL:diag_severity}>%{SPACE}<%{GREEDYDATA:diag_subSystem}>%{SPACE}<%{HOSTNAME:diag_machine}>%{SPACE}<%{HOSTNAME:diag_server}>%{SPACE}<%{DATA:diag_thread}>%{SPACE}<%{WORDNOBRACKET:diag_userId}>%{SPACE}<%{DATA:diag_transactionId}>%{SPACE}<%{WORDNOSPACES:diag_contextId}>%{SPACE}<%{NUMBER:diag_timestamp}>%{SPACE}<\[severity-value: %{INT:diag_severityValue}\]%{WEBLOGICLOGPARTITION}>%{SPACE}<%{DATA:diag_massageId}>%{SPACE}<%{WEBLOGICDIAGMESSAGE}>" ] - } - - mutate { - replace => ['diag_date', '%{tmp_month} %{tmp_day}, %{tmp_year} %{tmp_hour}:%{tmp_min}:%{tmp_second},%{tmp_sss} %{tmp_aa}'] - } - - translate { - field => 'diag_timezone' - destination => 'diag_timezone' - fallback => '%{diag_timezone}' - override => "true" - dictionary => { - "Coordinated Universal Time" => "UTC" - } - } - - date { - match => [ "diag_date", "MMM dd, YYYY KK:mm:ss,SSS aa", "MMM d, YYYY KK:mm:ss,SSS aa"] - timezone => "%{diag_timezone}" - target => "diag_date" - } - mutate { - remove_field => [ 'diag_timezone', 'tmp_month', 'tmp_day', 'tmp_year', 'tmp_hour', 'tmp_min', 'tmp_second', 'tmp_sss', 'tmp_aa'] - } - } - else if [type] == "datasource.log" { - mutate { replace => { type => "weblogic_datasource_log" } } - # with timestamp - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "####<%{WORDNOSPACES:ds_dataSource}>%{SPACE}<%{WORDNOSPACES:ds_profileType}>%{SPACE}<%{DSIDORTIMESTAMP}>%{SPACE}<%{DSWEBLOGICMESSAGE}>%{SPACE}<%{DATA:ds_info}>%{SPACE}<%{DSPARTITION}>" ] - } - - if ([db_month]) { - # DBDATETIME %{DAY} %{MONTH:db_month} %{MONTHDAY:db_day} %{HOUR:db_hour}:%{MINUTE:db_minute}:%{SECOND:db_second} %{TZ:db_tz} %{YEAR:db_year} - mutate { - replace => ["ds_timestamp", "%{db_month} %{db_day}, %{db_year} %{db_hour}:%{db_minute}:%{db_second}"] - } - - date { - match => [ "ds_timestamp", "MMM dd, YYYY HH:mm:ss", "MMM d, YYYY HH:mm:ss"] - timezone => "%{db_tz}" - target => "ds_timestamp" - } - mutate { - remove_field => [ 'db_month','db_day','db_year','db_hour','db_minute','db_second','db_tz'] - } - } - } - else if [type] == "${serverName}.out" { - mutate { replace => { type => "weblogic_std_log" } } - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "<%{WEBLOGICSTDDATE}%{SPACE}%{WORDWITHSPACE:out_timezone}>%{SPACE}<%{WORDWITHSPACE:out_level}>%{SPACE}<%{WORDWITHSPACE:out_subsystem}>%{SPACE}%{WEBLOGICSTDDYNAMICID}"] - } - - mutate { - replace => ['out_timestamp', '%{tmp_month} %{tmp_day}, %{tmp_year} %{tmp_hour}:%{tmp_min}:%{tmp_second} %{tmp_aa}'] - } - - # CEST id does not exist in JODA-TIME, changed to CET - translate { - field => 'out_timezone' - destination => 'out_timezone' - fallback => '%{out_timezone}' - override => "true" - dictionary => { - "CEST" => "CET" - "Coordinated Universal Time" => "UTC" - } - } - - date { - match => [ "out_timestamp", "MMM dd, YYYY KK:mm:ss aa", "MMM d, YYYY KK:mm:ss aa", "MMM dd, YYYY KK:mm:ss,SSS aa", "MMM d, YYYY KK:mm:ss,SSS aa"] - timezone => "%{out_timezone}" - target => "out_timestamp" - } - mutate { - remove_field => [ 'out_timezone','tmp_month', 'tmp_day', 'tmp_year', 'tmp_hour', 'tmp_min', 'tmp_second', 'tmp_aa'] - } - } - else if [type] == "nodemanager.log" { - mutate { replace => { type => "weblogic_nodemanager_log" } } - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "<%{WEBLOGICSTDDATE}%{SPACE}%{WORDWITHSPACE:node_timezone}>%{SPACE}<%{WORDWITHSPACE:node_level}>%{SPACE}%{NODEMANAGEREND}"] - } - - mutate { - replace => ['node_timestamp', '%{tmp_month} %{tmp_day}, %{tmp_year} %{tmp_hour}:%{tmp_min}:%{tmp_second} %{tmp_aa}'] - } - - # CEST id does not exist in JODA-TIME, changed to CET - translate { - field => 'node_timezone' - destination => 'node_timezone' - fallback => '%{node_timezone}' - override => "true" - dictionary => { - "CEST" => "CET" - "Coordinated Universal Time" => "UTC" - } - } - - date { - match => [ "node_timestamp", "MMM dd, YYYY KK:mm:ss aa", "MMM d, YYYY KK:mm:ss aa", "MMM dd, YYYY KK:mm:ss,SSS aa", "MMM d, YYYY KK:mm:ss,SSS aa"] - timezone => "%{node_timezone}" - target => "node_timestamp" - } - mutate { - remove_field => [ 'node_timezone','tmp_month', 'tmp_day', 'tmp_year', 'tmp_hour', 'tmp_min', 'tmp_second', 'tmp_aa'] - } - } -} -output { - elasticsearch { - hosts => "${elasticURI}" - user => "${elasticUserName}" - password => "${elasticPassword}" - index => "${logIndex}" - } -} -EOF - - # Add JAVA_HOME to startup.options - cp /etc/logstash/startup.options /etc/logstash/startup.options.elksave - sed -i -e "/JAVACMD/a\\JAVA_HOME=${JAVA_HOME}" /etc/logstash/startup.options - sed -i -e "s:LS_USER=.*:LS_USER=${userOracle}:g" /etc/logstash/startup.options - sed -i -e "s:LS_GROUP=.*:LS_GROUP=${groupOracle}:g" /etc/logstash/startup.options - - # For Java 11 - # ISSUE: https://github.com/elastic/logstash/issues/10496 - java_version=$(java -version 2>&1 | sed -n ';s/.* version "\(.*\)\.\(.*\)\..*"/\1\2/p;') - if [ ${java_version:0:3} -ge 110 ]; then - cp /etc/logstash/jvm.options /etc/logstash/jvm.options.elksave - cat <>/etc/logstash/jvm.options ---add-opens java.base/sun.nio.ch=org.jruby.dist ---add-opens java.base/java.io=org.jruby.dist -EOF - fi - - # create start up for logstash - /usr/share/logstash/bin/system-install /etc/logstash/startup.options - if [ $? -ne 0 ]; then - echo_stderr "Failed to set up logstash service." - exit 1 - fi - - sudo chown -R ${userOracle}:${groupOracle} /var/lib/logstash - sudo chown -R ${userOracle}:${groupOracle} /etc/logstash -} - -function configure_wls_log() { - echo "Configure WebLogic Log" - sudo chown -R ${userOracle}:${groupOracle} ${SCRIPT_PATH} - runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST ${SCRIPT_PATH}/configure-wls-log.py" - - errorCode=$? - if [ $errorCode -eq 1 ]; then - echo "Exception occurs during ELK configuration, please check." - exit 1 - fi -} - -function setup_javahome() { - . $oracleHome/oracle_common/common/bin/setWlstEnv.sh -} - -function restart_admin_service() { - echo "Restart weblogic admin server" - echo "Stop admin server" - shutdown_admin - sudo systemctl start wls_admin - echo "Waiting for admin server to be available" - wait_for_admin - echo "Weblogic admin server is up and running" -} - -function restartManagedServers() { - echo "Restart managed servers" - cat <${SCRIPT_PATH}/restart-managedServer.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') -servers=cmo.getServers() -domainRuntime() -print "Restart the servers which are in RUNNING status" -for server in servers: - bean="/ServerLifeCycleRuntimes/"+server.getName() - serverbean=getMBean(bean) - if (serverbean.getState() in ("RUNNING")) and (server.getName() != '${wlsAdminServerName}'): - try: - print "Stop the Server ",server.getName() - shutdown(server.getName(),server.getType(),ignoreSessions='true',force='true') - print "Start the Server ",server.getName() - start(server.getName(),server.getType()) - except: - print "Failed restarting managed server ", server.getName() - dumpStack() -serverConfig() -disconnect() -EOF - sudo chown -R ${userOracle}:${groupOracle} ${SCRIPT_PATH} - runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST ${SCRIPT_PATH}/restart-managedServer.py" - - if [[ $? != 0 ]]; then - echo "Error : Fail to restart managed server to sync up elk configuration." - exit 1 - fi -} - -#This function to check admin server status -function wait_for_admin() { - #check admin server status - count=1 - CHECK_URL="http://$wlsAdminURL/weblogic/ready" - status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) - echo "Check admin server status" - while [[ "$status" != "200" ]]; do - echo "." - count=$((count + 1)) - if [ $count -le 30 ]; then - sleep 1m - else - echo "Error : Maximum attempts exceeded while checking admin server status" - exit 1 - fi - status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) - if [ "$status" == "200" ]; then - echo "WebLogic Server is running..." - break - fi - done -} - -# shutdown admin server -function shutdown_admin() { - #check admin server status - count=1 - CHECK_URL="http://$wlsAdminURL/weblogic/ready" - status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) - echo "Check admin server status" - while [[ "$status" == "200" ]]; do - echo "." - count=$((count + 1)) - sudo systemctl stop wls_admin - if [ $count -le 30 ]; then - sleep 1m - else - echo "Error : Maximum attempts exceeded while stopping admin server" - exit 1 - fi - status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) - if [ -z ${status} ]; then - echo "WebLogic Server is stop..." - break - fi - done -} - -function cleanup() { - echo "Cleaning up temporary files..." - rm -f -r ${SCRIPT_PATH} - echo "Cleanup completed." -} - -function create_temp_folder() -{ - SCRIPT_PATH="/u01/tmp" - sudo rm -f -r ${SCRIPT_PATH} - sudo mkdir ${SCRIPT_PATH} - sudo rm -rf $SCRIPT_PATH/* -} - -function validate_elastic_server() -{ - timestamp=$(date +%s) - testIndex="${logIndex}-validate-elk-server-from-server-${index}-${timestamp}" - output=$(curl -XPUT --user ${elasticUserName}:${elasticPassword} ${elasticURI}/${testIndex}) - if [[ $? -eq 1 || -z `echo $output | grep "\"acknowledged\":true"` ]];then - echo $output - exit 1 - fi - - count=1 - status404="\"status\":404" - while [[ -n ${status404} ]]; do - echo "." - count=$((count + 1)) - # remove the test index - echo "Removing test index..." - curl -XDELETE --user ${elasticUserName}:${elasticPassword} ${elasticURI}/${testIndex} - echo "Checking if test index is removed." - status404=$(curl -XGET --user ${elasticUserName}:${elasticPassword} ${elasticURI}/${testIndex} | grep "\"status\":404") - echo ${status404} - if [[ -n ${status404} ]]; then - echo "Test index is removed..." - break - fi - - if [ $count -le 30 ]; then - sleep 1m - else - echo "Error : Maximum attempts exceeded while removing test index from elastic server" - exit 1 - fi - done -} - -# main script starts from here - -SCRIPT_PWD=$(pwd) - -#read arguments from stdin -read oracleHome wlsAdminURL wlsUserName wlsPassword wlsAdminServerName elasticURI elasticUserName elasticPassword wlsDomainName wlsDomainPath logsToIntegrate index logIndex managedServerPrefix - -hostName=$(hostname) -userOracle="oracle" -groupOracle="oracle" - -create_temp_folder -validate_input -validate_elastic_server - -echo "start to configure ELK" -setup_javahome - -if [ $index -eq 0 ]; then - create_wls_log_model - configure_wls_log - restart_admin_service - restartManagedServers -fi - -remove_logstash -install_logstash -configure_lostash -start_logstash -cleanup diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/installJdbcDrivers.sh b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/installJdbcDrivers.sh new file mode 100644 index 000000000..e01ed72ed --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/installJdbcDrivers.sh @@ -0,0 +1,252 @@ +# Copyright (c) 2021, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +# Description +# This script is to install jdbc libraries at WebLogic cluster domain. + +# /bin/bash + +#Function to output message to StdErr +function echo_stderr() { + echo "$@" >&2 +} + +#Function to display usage message +function usage() { + echo_stderr "./installJdbcDrivers.sh <<< \"\"" +} + +function validate_input() { + + # parse base64 string + wlsShibboleth=$(echo "${wlsShibboleth}" | base64 -d) + + if [ -z "$oracleHome" ]; then + echo _stderr "Please provide oracleHome" + exit 1 + fi + + if [ -z "$domainPath" ]; then + echo _stderr "Please provide domainPath" + exit 1 + fi + + if [ -z "$wlsServerName" ]; then + echo _stderr "Please provide wlsServerName" + exit 1 + fi + + if [ -z "$wlsAdminHost" ]; then + echo _stderr "Please provide wlsAdminHost" + exit 1 + fi + + if [ -z "$wlsAdminPort" ]; then + echo _stderr "Please provide wlsAdminPort" + exit 1 + fi + + if [ -z "$wlsUserName" ]; then + echo _stderr "Please provide weblogic username" + exit 1 + fi + + if [ -z "$wlsShibboleth" ]; then + echo _stderr "Please provide weblogic password" + exit 1 + fi + + if [ -z "$databaseType" ]; then + echo _stderr "Please provide databaseType" + exit 1 + fi + + if [ -z "$enablePswlessConnection" ]; then + echo _stderr "Please provide enablePswlessConnection" + exit 1 + fi +} + +function install_maven() { + sudo yum install maven -y +} + +function uninstall_maven() { + sudo yum remove maven -y +} + +function install_azure_identity_extension() { + local myPomFile=pom.xml + curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -fksL "${gitUrl4AzureIdentityExtensionPomFile}" -o ${myPomFile} + if [ $? != 0 ]; then + echo_stderr "Failed to download ${gitUrl4AzureIdentityExtensionPomFile}." + fi + + echo "download dependencies" + mvn dependency:copy-dependencies -f ${myPomFile} + if [ $? -eq 0 ]; then + ls -l target/dependency/ + + domainBase=$(dirname $domainPath) + + # check if azure identity extension has been installed, if so, remove old version + if [ -d "${domainBase}/azure-libraries/identity" ]; then + sudo rm ${domainBase}/azure-libraries/identity -f -r + sudo rm ${domainBase}/azure-libraries/jackson -f -r + fi + + sudo mkdir -p ${domainBase}/azure-libraries/identity + sudo mkdir -p ${domainBase}/azure-libraries/jackson + # fix JARs conflict issue, put jackson libraries to PRE_CLASSPATH to upgrade the existing libs. + sudo mv target/dependency/jackson-annotations-*.jar ${domainBase}/azure-libraries/jackson + sudo mv target/dependency/jackson-core-*.jar ${domainBase}/azure-libraries/jackson + sudo mv target/dependency/jackson-databind-*.jar ${domainBase}/azure-libraries/jackson + sudo mv target/dependency/jackson-dataformat-xml-*.jar ${domainBase}/azure-libraries/jackson + # Those jars will be appended to CLASSPATH + sudo mv target/dependency/*.jar ${domainBase}/azure-libraries/identity + sudo chown -R oracle:oracle ${domainBase}/azure-libraries + else + echo "Failed to download dependencies for azure-identity-extension" + exit 1 + fi + + rm ${myPomFile} -f + rm target -f -r + if ! grep -q "${domainBase}/azure-libraries/identity/" "${domainPath}/bin/setDomainEnv.sh"; then + sed -i 's;^export DOMAIN_HOME;&\nCLASSPATH="'${domainBase}'/azure-libraries/identity/*:${CLASSPATH}";' ${domainPath}/bin/setDomainEnv.sh + fi + + if ! grep -q "${domainBase}/azure-libraries/jackson/" "${domainPath}/bin/setDomainEnv.sh"; then + sed -i 's;^export DOMAIN_HOME;&\nPRE_CLASSPATH="'${domainBase}'/azure-libraries/jackson/*:${PRE_CLASSPATH}";' ${domainPath}/bin/setDomainEnv.sh + fi +} + +function upgrade_mysql_driver() { + local mysqlPomFile=mysql-pom.xml + curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -fksL "${gitUrl4MySQLDriverPomFile}" -o ${mysqlPomFile} + if [ $? != 0 ]; then + echo_stderr "Failed to download ${gitUrl4MySQLDriverPomFile}." + fi + + echo "download dependencies" + mvn dependency:copy-dependencies -f ${mysqlPomFile} + if [ $? -eq 0 ]; then + ls -l target/dependency/ + + local domainBase=$(dirname $domainPath) + local preClassLibsFolderName=preclasspath-libraries + + # check if the driver has been upgraded, if so, remove old driver + if [ -e ${domainBase}/${preClassLibsFolderName}/mysql-connector-*.jar ]; then + sudo rm ${domainBase}/${preClassLibsFolderName} -f -r + fi + + sudo mkdir ${domainBase}/${preClassLibsFolderName} + sudo mv target/dependency/mysql-connector-*.jar ${domainBase}/${preClassLibsFolderName}/ + sudo chown -R oracle:oracle ${domainBase}/${preClassLibsFolderName} + else + echo "Failed to download mysql driver." + exit 1 + fi + + rm ${mysqlPomFile} -f + rm target -f -r + + if ! grep -q "${domainBase}/preclasspath-libraries/" "${domainPath}/bin/setDomainEnv.sh"; then + sed -i 's;^export DOMAIN_HOME;&\nPRE_CLASSPATH="'${domainBase}'/preclasspath-libraries/*:${PRE_CLASSPATH}";' ${domainPath}/bin/setDomainEnv.sh + fi +} + +#This function to wait for admin server +function wait_for_admin() { + #wait for admin to start + count=1 + CHECK_URL="http://$wlsAdminURL/weblogic/ready" + status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) + echo "Waiting for admin server to start" + while [[ "$status" != "200" ]]; do + echo "." + count=$((count + 1)) + if [ $count -le 30 ]; then + sleep 1m + else + echo "Error : Maximum attempts exceeded while starting admin server" + exit 1 + fi + status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) + if [ "$status" == "200" ]; then + echo "Admin Server started succesfully..." + break + fi + done +} + +function restart_admin_service() { + echo "Restart weblogic admin server service" + sudo systemctl stop wls_admin + sudo systemctl start wls_admin + wait_for_admin +} + +function restart_managed_servers() { + echo "Restart managed servers" + cat <${SCRIPT_PWD}/restart-managedServer.py +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') +servers=cmo.getServers() +domainRuntime() +print "Restart the servers which are in RUNNING status" +for server in servers: + bean="/ServerLifeCycleRuntimes/"+server.getName() + serverbean=getMBean(bean) + if (serverbean.getState() in ("RUNNING")) and (server.getName() == '${wlsServerName}'): + try: + print "Stop the Server ",server.getName() + shutdown(server.getName(),server.getType(),ignoreSessions='true',force='true') + print "Start the Server ",server.getName() + start(server.getName(),server.getType()) + break + except: + print "Failed restarting managed server ", server.getName() + dumpStack() +serverConfig() +disconnect() +EOF + . $oracleHome/oracle_common/common/bin/setWlstEnv.sh + java $WLST_ARGS weblogic.WLST ${SCRIPT_PWD}/restart-managedServer.py + + if [[ $? != 0 ]]; then + echo "Error : Fail to restart managed server to configuration external libraries." + exit 1 + fi +} + +#read arguments from stdin +read oracleHome domainPath wlsServerName wlsAdminHost wlsAdminPort wlsUserName wlsShibboleth databaseType enablePswlessConnection + +export curlMaxTime=120 # seconds +export gitUrl4AzureIdentityExtensionPomFile="https://raw.githubusercontent.com/oracle/weblogic-azure/main/weblogic-azure-aks/src/main/resources/azure-identity-extensions.xml" +export gitUrl4MySQLDriverPomFile="https://raw.githubusercontent.com/oracle/weblogic-azure/main/weblogic-azure-aks/src/main/resources/mysql-connector-java.xml" +export retryMaxAttempt=5 # retry attempt for curl command + +export wlsAdminURL=$wlsAdminHost:$wlsAdminPort + +validate_input + +install_maven + +if [ $databaseType == "mysql" ]; then + upgrade_mysql_driver +fi + +if [ "${enablePswlessConnection,,}" == "true" ]; then + if [[ $databaseType == "mysql" || $databaseType == "postgresql" ]]; then + install_azure_identity_extension + fi +fi + +uninstall_maven + +if [ $wlsServerName == "admin" ]; then + restart_admin_service +else + restart_managed_servers +fi diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/postDeploymentScript.sh b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/postDeploymentScript.sh new file mode 100644 index 000000000..cc3790ae2 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/postDeploymentScript.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# Copyright (c) 2021, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +#Function to output message to StdErr +function echo_stderr () +{ + echo "$@" >&2 +} + +#Function to display usage message +function usage() +{ + echo_stderr "./postDeploymentScript.sh " +} + + + +echo "Executing post Deployment script" + +# Get all public ips assigned to the network interface in a given resource group, and follow the below steps +# 1) Get the resource (public IP) tagged with supplied resource tag +# 2) Remove the public IP from netwrok interface +# 3) Finally delete all public IPs + +PUBLIC_IPS="$(az network public-ip list --resource-group ${RESOURCE_GROUP_NAME} --query "[?tags && contains(keys(tags), '${GUID_TAG}')].id" -o tsv)" +if [ -n "${PUBLIC_IPS}" ]; then + echo "Found public IPs to remove: ${PUBLIC_IPS}" + for PUBLIC_IP in ${PUBLIC_IPS}; do + IP_CONFIG_ID=$(az network public-ip show --ids "${PUBLIC_IP}" --query "ipConfiguration.id" -o tsv) + if [ -n "${IP_CONFIG_ID}" ]; then + echo "Found IP configuration: ${IP_CONFIG_ID}" + # Using IP configuration id extract Network interface name and IP config name + NIC_NAME=$(echo "${IP_CONFIG_ID}" | sed 's|.*/networkInterfaces/\([^/]*\)/.*|\1|') + IP_CONFIG_NAME=$(echo "${IP_CONFIG_ID}" | sed 's|.*/ipConfigurations/\([^/]*\).*|\1|') + echo "Removing public IP from NIC: ${NIC_NAME}, IP config: ${IP_CONFIG_NAME}" + az network nic ip-config update -g "${RESOURCE_GROUP_NAME}" --nic-name "${NIC_NAME}" -n "${IP_CONFIG_NAME}" --remove publicIPAddress + fi + done + echo "Deleting public IPs: ${PUBLIC_IPS}" + az network public-ip delete --ids ${PUBLIC_IPS} +else + echo "No public IPs found with tag ${GUID_TAG}" +fi +echo "Deleting $MANAGED_IDENTITY_ID " +az identity delete --ids $MANAGED_IDENTITY_ID \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/setupApplicationGateway.sh b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/setupApplicationGateway.sh index a44b5726e..5fdb55b9f 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/setupApplicationGateway.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/setupApplicationGateway.sh @@ -23,9 +23,9 @@ function validateInput() echo_stderr "wlsAdminServerName is required. " fi - if [[ -z "$wlsUserName" || -z "$wlsPassword" ]] + if [[ -z "$wlsUserName" || -z "$wlsShibboleth" ]] then - echo_stderr "wlsUserName or wlsPassword is required. " + echo_stderr "Weblogic username or password is required. " exit 1 fi @@ -51,7 +51,7 @@ function validateInput() function setupApplicationGateway() { cat <$SCRIPT_PWD/setup-app-gateway.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') edit("$wlsAdminServerName") startEdit() @@ -107,7 +107,7 @@ function restartManagedServers() { echo "Restart managed servers" cat <${SCRIPT_PWD}/restart-managedServer.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') servers=cmo.getServers() domainRuntime() print "Restart the servers which are in RUNNING status" @@ -140,7 +140,7 @@ EOF SCRIPT_PWD=`pwd` #read arguments from stdin -read wlsAdminServerName wlsUserName wlsPassword wlsAdminHost wlsAdminPort AppGWHostName oracleHome +read wlsAdminServerName wlsUserName wlsShibboleth wlsAdminHost wlsAdminPort AppGWHostName oracleHome wlsAdminURL=$wlsAdminHost:$wlsAdminPort @@ -152,4 +152,4 @@ validateInput setupApplicationGateway -restartManagedServers \ No newline at end of file +restartManagedServers diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/setupClusterDomain.sh b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/setupClusterDomain.sh index 8c4bb1939..02bb0fadf 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/setupClusterDomain.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/setupClusterDomain.sh @@ -47,9 +47,9 @@ function validateInput() echo_stderr "wlsDomainName is required. " fi - if [[ -z "$wlsUserName" || -z "$wlsPassword" ]] + if [[ -z "$wlsUserName" || -z "$wlsShibboleth" ]] then - echo_stderr "wlsUserName or wlsPassword is required. " + echo_stderr "Weblogic username or password is required. " exit 1 fi @@ -103,6 +103,18 @@ function validateInput() exit 1 fi fi + + if [ -z "$virtualNetworkNewOrExisting" ]; + then + echo_stderr "virtualNetworkNewOrExisting is required. " + exit 1 + fi + + if [ -z "$storageAccountPrivateIp" ]; + then + echo_stderr "storageAccountPrivateIp is required. " + exit 1 + fi } #Function to cleanup all temporary files @@ -112,12 +124,62 @@ function cleanup() rm -rf $DOMAIN_PATH/admin-domain.yaml rm -rf $DOMAIN_PATH/managed-domain.yaml - rm -rf $DOMAIN_PATH/deploy-app.yaml - rm -rf $DOMAIN_PATH/shoppingcart.zip rm -rf $DOMAIN_PATH/*.py + rm -rf ${CUSTOM_HOSTNAME_VERIFIER_HOME} echo "Cleanup completed." } +# This function verifies whether certificate is valid and not expired +function verifyCertValidity() +{ + KEYSTORE=$1 + PASSWORD=$2 + CURRENT_DATE=$3 + MIN_CERT_VALIDITY=$4 + KEY_STORE_TYPE=$5 + VALIDITY=$(($CURRENT_DATE + ($MIN_CERT_VALIDITY*24*60*60))) + + echo "Verifying $KEYSTORE is valid at least $MIN_CERT_VALIDITY day from the deployment time" + + if [ $VALIDITY -le $CURRENT_DATE ]; + then + echo "Error : Invalid minimum validity days supplied" + exit 1 + fi + + # Check whether KEYSTORE supplied can be opened for reading + # Redirecting as no need to display the contents + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $KEYSTORE -storepass $PASSWORD -storetype $KEY_STORE_TYPE > /dev/null 2>&1" + if [ $? != 0 ]; + then + echo "Error opening the keystore : $KEYSTORE" + exit 1 + fi + + aliasList=`runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $KEYSTORE -storepass $PASSWORD -storetype $KEY_STORE_TYPE | grep Alias" |awk '{print $3}'` + if [[ -z $aliasList ]]; + then + echo "Error : No alias found in supplied certificate" + exit 1 + fi + + for alias in $aliasList + do + VALIDITY_PERIOD=`runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $KEYSTORE -storepass $PASSWORD -storetype $KEY_STORE_TYPE -alias $alias | grep Valid"` + echo "$KEYSTORE is \"$VALIDITY_PERIOD\"" + CERT_UNTIL_DATE=`echo $VALIDITY_PERIOD | awk -F'until:|\r' '{print $2}'` + CERT_UNTIL_SECONDS=`date -d "$CERT_UNTIL_DATE" +%s` + VALIDITY_REMIANS_SECONDS=`expr $CERT_UNTIL_SECONDS - $VALIDITY` + if [[ $VALIDITY_REMIANS_SECONDS -le 0 ]]; + then + echo_stderr "$KEYSTORE is \"$VALIDITY_PERIOD\"" + echo_stderr "Error : Supplied certificate $KEYSTORE is either expired or expiring soon within $MIN_CERT_VALIDITY day" + exit 1 + fi + done + echo "$KEYSTORE validation is successful" +} + #Creates weblogic deployment model for cluster domain admin setup function create_admin_model() { @@ -128,7 +190,7 @@ cat /dev/null > $DOMAIN_PATH/admin-domain.yaml cat <$DOMAIN_PATH/admin-domain.yaml domainInfo: AdminUserName: "$wlsUserName" - AdminPassword: "$wlsPassword" + AdminPassword: "$wlsShibboleth" ServerStartMode: prod topology: Name: "$wlsDomainName" @@ -153,6 +215,8 @@ topology: Enabled: true ListenPortEnabled: ${isHTTPAdminListenPortEnabled} RestartDelaySeconds: 10 + ServerStart: + Arguments: '${SERVER_STARTUP_ARGS}' EOF if [ "${isCustomSSLEnabled}" == "true" ]; @@ -172,8 +236,6 @@ cat <>$DOMAIN_PATH/admin-domain.yaml SSL: ListenPort: $wlsSSLAdminPort Enabled: true - HostnameVerificationIgnored: true - HostnameVerifier: 'None' EOF if [ "${isCustomSSLEnabled}" == "true" ]; @@ -187,8 +249,20 @@ EOF cat <>$DOMAIN_PATH/admin-domain.yaml SecurityConfiguration: NodeManagerUsername: "$wlsUserName" - NodeManagerPasswordEncrypted: "$wlsPassword" + NodeManagerPasswordEncrypted: "$wlsShibboleth" +EOF + +hasRemoteAnonymousAttribs="$(containsRemoteAnonymousT3RMIIAttribs)" +echo "hasRemoteAnonymousAttribs: ${hasRemoteAnonymousAttribs}" + +if [ "${hasRemoteAnonymousAttribs}" == "true" ]; +then +echo "adding settings to disable remote anonymous t3/rmi disabled under domain security configuration" +cat <>$DOMAIN_PATH/admin-domain.yaml + RemoteAnonymousRmiiiopEnabled: false + RemoteAnonymousRmit3Enabled: false EOF +fi } #Creates weblogic deployment model for cluster domain managed server @@ -198,14 +272,14 @@ function create_managed_model() cat <$DOMAIN_PATH/managed-domain.yaml domainInfo: AdminUserName: "$wlsUserName" - AdminPassword: "$wlsPassword" + AdminPassword: "$wlsShibboleth" ServerStartMode: prod topology: Name: "$wlsDomainName" Machine: - '$nmHost': + '$managedServerHost': NodeManager: - ListenAddress: "$nmHost" + ListenAddress: "$managedServerHost" ListenPort: $nmPort NMType : ssl Cluster: @@ -213,10 +287,13 @@ topology: MigrationBasis: 'consensus' Server: '$wlsServerName' : + ListenAddress: "$managedServerHost" ListenPort: $wlsManagedPort Notes: "$wlsServerName managed server" Cluster: "$wlsClusterName" - Machine: "$nmHost" + Machine: "$managedServerHost" + ServerStart: + Arguments: '${SERVER_STARTUP_ARGS} -Dweblogic.Name=$wlsServerName -Dweblogic.management.server=${SERVER_START_URL}' EOF if [ "${isCustomSSLEnabled}" == "true" ]; @@ -232,15 +309,10 @@ cat <>$DOMAIN_PATH/managed-domain.yaml EOF fi -cat <>$DOMAIN_PATH/managed-domain.yaml - SSL: - HostnameVerificationIgnored: true - HostnameVerifier: 'None' -EOF - if [ "${isCustomSSLEnabled}" == "true" ]; then cat <>$DOMAIN_PATH/managed-domain.yaml + SSL: ServerPrivateKeyAlias: "$serverPrivateKeyAlias" ServerPrivateKeyPassPhraseEncrypted: "$serverPrivateKeyPassPhrase" EOF @@ -249,8 +321,22 @@ EOF cat <>$DOMAIN_PATH/managed-domain.yaml SecurityConfiguration: NodeManagerUsername: "$wlsUserName" - NodeManagerPasswordEncrypted: "$wlsPassword" + NodeManagerPasswordEncrypted: "$wlsShibboleth" +EOF + +hasRemoteAnonymousAttribs="$(containsRemoteAnonymousT3RMIIAttribs)" +echo "hasRemoteAnonymousAttribs: ${hasRemoteAnonymousAttribs}" + + +if [ "${hasRemoteAnonymousAttribs}" == "true" ]; +then +echo "adding settings to disable remote anonymous t3/rmi disabled under domain security configuration" +cat <>$DOMAIN_PATH/managed-domain.yaml + RemoteAnonymousRmiiiopEnabled: false + RemoteAnonymousRmit3Enabled: false EOF +fi + } #This function to add machine for a given managed server @@ -258,7 +344,7 @@ function create_machine_model() { echo "Creating machine name model for managed server $wlsServerName" cat <$DOMAIN_PATH/add-machine.py -connect('$wlsUserName','$wlsPassword','$adminWlstURL') +connect('$wlsUserName','$wlsShibboleth','$adminWlstURL') edit("$wlsServerName") startEdit() cd('/') @@ -282,7 +368,7 @@ function create_ms_server_model() cat <$DOMAIN_PATH/add-server.py isCustomSSLEnabled='${isCustomSSLEnabled}' -connect('$wlsUserName','$wlsPassword','$adminWlstURL') +connect('$wlsUserName','$wlsShibboleth','$adminWlstURL') edit("$wlsServerName") startEdit() cd('/') @@ -306,11 +392,15 @@ if isCustomSSLEnabled == 'true' : cd('/Servers/$wlsServerName/SSL/$wlsServerName') cmo.setServerPrivateKeyAlias('$serverPrivateKeyAlias') set('ServerPrivateKeyPassPhrase', '$serverPrivateKeyPassPhrase') -cmo.setHostnameVerificationIgnored(true) cd('/Servers/$wlsServerName//ServerStart/$wlsServerName') -arguments = '-Dweblogic.Name=$wlsServerName -Dweblogic.management.server=${SERVER_START_URL} -Dweblogic.security.SSL.ignoreHostnameVerification=true' -cmo.setArguments(arguments) +arguments = '${SERVER_STARTUP_ARGS} -Dweblogic.Name=$wlsServerName -Dweblogic.management.server=${SERVER_START_URL}' +oldArgs = cmo.getArguments() +if oldArgs != None: + newArgs = oldArgs + ' ' + arguments +else: + newArgs = arguments +cmo.setArguments(newArgs) save() resolve() activate() @@ -338,7 +428,6 @@ function create_adminSetup() exit 1 fi - storeCustomSSLCerts create_admin_model sudo chown -R $username:$groupname $DOMAIN_PATH runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; $DOMAIN_PATH/weblogic-deploy/bin/createDomain.sh -oracle_home $oracleHome -domain_parent $DOMAIN_PATH -domain_type WLS -model_file $DOMAIN_PATH/admin-domain.yaml" @@ -358,7 +447,7 @@ function admin_boot_setup() #Create the boot.properties directory mkdir -p "$DOMAIN_PATH/$wlsDomainName/servers/admin/security" echo "username=$wlsUserName" > "$DOMAIN_PATH/$wlsDomainName/servers/admin/security/boot.properties" - echo "password=$wlsPassword" >> "$DOMAIN_PATH/$wlsDomainName/servers/admin/security/boot.properties" + echo "password=$wlsShibboleth" >> "$DOMAIN_PATH/$wlsDomainName/servers/admin/security/boot.properties" sudo chown -R $username:$groupname $DOMAIN_PATH/$wlsDomainName/servers } @@ -390,6 +479,26 @@ do done } +#This function to wait for packaged domain availability at ${mountpointPath} by checking ${wlsDomainName}-pack.complete +function wait_for_packaged_template() +{ + #wait for packaged domain template to be available + count=1 + echo "Waiting for packaged domain template availability ${mountpointPath}/${wlsDomainName}-template.jar" + while [ ! -f ${mountpointPath}/${wlsDomainName}-pack.complete ] + do + echo "." + count=$((count+1)) + if [ $count -le 30 ]; + then + sleep 1m + else + echo "Error : Maximum attempts exceeded for waiting packaged domain template ${mountpointPath}/${wlsDomainName}-template.jar" + exit 1 + fi + done +} + # Create systemctl service for nodemanager function create_nodemanager_service() { @@ -428,9 +537,10 @@ Wants=network-online.target Type=simple # Note that the following three parameters should be changed to the correct paths # on your own system -WorkingDirectory="$DOMAIN_PATH/$wlsDomainName" -ExecStart="$DOMAIN_PATH/$wlsDomainName/bin/startNodeManager.sh" -ExecStop="$DOMAIN_PATH/$wlsDomainName/bin/stopNodeManager.sh" +WorkingDirectory=/u01/domains +Environment="JAVA_OPTIONS=${SERVER_STARTUP_ARGS}" +ExecStart=/bin/bash $DOMAIN_PATH/$wlsDomainName/bin/startNodeManager.sh +ExecStop=/bin/bash $DOMAIN_PATH/$wlsDomainName/bin/stopNodeManager.sh User=oracle Group=oracle KillMode=process @@ -456,9 +566,10 @@ Wants=network-online.target [Service] Type=simple -WorkingDirectory="$DOMAIN_PATH/$wlsDomainName" -ExecStart="${startWebLogicScript}" -ExecStop="${stopWebLogicScript}" +WorkingDirectory=/u01/domains +Environment="JAVA_OPTIONS=${SERVER_STARTUP_ARGS}" +ExecStart=/bin/bash ${startWebLogicScript} +ExecStop=/bin/bash ${stopWebLogicScript} User=oracle Group=oracle KillMode=process @@ -476,7 +587,7 @@ function start_managed() { echo "Starting managed server $wlsServerName" cat <$DOMAIN_PATH/start-server.py -connect('$wlsUserName','$wlsPassword','$adminWlstURL') +connect('$wlsUserName','$wlsShibboleth','$adminWlstURL') try: start('$wlsServerName', 'Server') except: @@ -507,37 +618,39 @@ function create_managedSetup(){ exit 1 fi - storeCustomSSLCerts - echo "Creating managed server model files" create_managed_model - create_machine_model - create_ms_server_model + # Following are not requires as it is taken care by create_managed_model applied on existing domain + #create_machine_model + #create_ms_server_model echo "Completed managed server model files" sudo chown -R $username:$groupname $DOMAIN_PATH - runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; $DOMAIN_PATH/weblogic-deploy/bin/createDomain.sh -oracle_home $oracleHome -domain_parent $DOMAIN_PATH -domain_type WLS -model_file $DOMAIN_PATH/managed-domain.yaml" + # Updating managed-domain.yaml using updateDomain.sh on existing domain created by create_admin_model + # wlsShibboleth is accepted from stdin to support old and new weblogic-deploy tool version + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; $DOMAIN_PATH/weblogic-deploy/bin/updateDomain.sh -admin_url $adminWlstURL -admin_user $wlsUserName -oracle_home $oracleHome -domain_home $DOMAIN_PATH/${wlsDomainName} -domain_type WLS -model_file $DOMAIN_PATH/managed-domain.yaml <<< $wlsShibboleth" if [[ $? != 0 ]]; then echo "Error : Managed setup failed" exit 1 fi - wait_for_admin + + # Following are not required as updateDomain.sh with managed-domain.yaml will take care of following + #wait_for_admin + ## For issue https://github.com/wls-eng/arm-oraclelinux-wls/issues/89 + #getSerializedSystemIniFileFromShare - # For issue https://github.com/wls-eng/arm-oraclelinux-wls/issues/89 - getSerializedSystemIniFileFromShare - - echo "Adding machine to managed server $wlsServerName" - runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST $DOMAIN_PATH/add-machine.py" - if [[ $? != 0 ]]; then - echo "Error : Adding machine for managed server $wlsServerName failed" - exit 1 - fi - echo "Adding managed server $wlsServerName" - runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST $DOMAIN_PATH/add-server.py" - if [[ $? != 0 ]]; then - echo "Error : Adding server $wlsServerName failed" - exit 1 - fi + #echo "Adding machine to managed server $wlsServerName" + #runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST $DOMAIN_PATH/add-machine.py" + #if [[ $? != 0 ]]; then + #echo "Error : Adding machine for managed server $wlsServerName failed" + #exit 1 + #fi + #echo "Adding managed server $wlsServerName" + #runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST $DOMAIN_PATH/add-server.py" + #if [[ $? != 0 ]]; then + #echo "Error : Adding server $wlsServerName failed" + #exit 1 + #fi } function enabledAndStartNodeManagerService() @@ -622,13 +735,13 @@ function mountFileShare() fi echo "chmod 600 /etc/smbcredentials/${storageAccountName}.cred" sudo chmod 600 /etc/smbcredentials/${storageAccountName}.cred - echo "//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred ,dir_mode=0777,file_mode=0777,serverino" - sudo bash -c "echo \"//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred ,dir_mode=0777,file_mode=0777,serverino\" >> /etc/fstab" - echo "mount -t cifs //${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino" - sudo mount -t cifs //${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino + echo "//${storageAccountPrivateIp}/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino" + sudo bash -c "echo \"//${storageAccountPrivateIp}/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino\" >> /etc/fstab" + echo "mount -t cifs //${storageAccountPrivateIp}/wlsshare $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino" + sudo mount -t cifs //${storageAccountPrivateIp}/wlsshare $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino if [[ $? != 0 ]]; then - echo "Failed to mount //${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath" + echo "Failed to mount //${storageAccountPrivateIp}/wlsshare $mountpointPath" exit 1 fi } @@ -645,6 +758,9 @@ function validateSSLKeyStores() exit 1 fi + # Verify Identity keystore validity period more than MIN_CERT_VALIDITY + verifyCertValidity $customIdentityKeyStoreFileName $customIdentityKeyStorePassPhrase $CURRENT_DATE $MIN_CERT_VALIDITY $customIdentityKeyStoreType + #validate Trust keystore runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $customTrustKeyStoreFileName -storepass $customTrustKeyStorePassPhrase -storetype $customTrustKeyStoreType | grep 'Entry type:' | grep 'trustedCertEntry'" @@ -653,6 +769,9 @@ function validateSSLKeyStores() exit 1 fi + # Verify Identity keystore validity period more than MIN_CERT_VALIDITY + verifyCertValidity $customTrustKeyStoreFileName $customTrustKeyStorePassPhrase $CURRENT_DATE $MIN_CERT_VALIDITY $customTrustKeyStoreType + echo "ValidateSSLKeyStores Successfull !!" } @@ -734,13 +853,151 @@ sudo chmod -R 750 ${stopWebLogicScript} } +#this function set the umask 027 (chmod 740) as required by WebLogic security checks +function setUMaskForSecurityDir() +{ + echo "setting umask 027 (chmod 740) for domain/$wlsServerName security directory" + + if [ -f "$DOMAIN_PATH/$wlsDomainName/servers/$wlsServerName/security/boot.properties" ]; + then + runuser -l oracle -c "chmod 740 $DOMAIN_PATH/$wlsDomainName/servers/$wlsServerName/security/boot.properties" + fi + + if [ -d "$DOMAIN_PATH/$wlsDomainName/servers/$wlsServerName/security" ]; + then + runuser -l oracle -c "chmod 740 $DOMAIN_PATH/$wlsDomainName/servers/$wlsServerName/security" + fi +} + +#this function checks if remote Anonymous T3/RMI Attributes are available as part of domain security configuration +function containsRemoteAnonymousT3RMIIAttribs() +{ + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; $DOMAIN_PATH/weblogic-deploy/bin/modelHelp.sh -oracle_home $oracleHome topology:/SecurityConfiguration | grep RemoteAnonymousRmiiiopEnabled" >> /dev/null + + result1=$? + + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; $DOMAIN_PATH/weblogic-deploy/bin/modelHelp.sh -oracle_home $oracleHome topology:/SecurityConfiguration | grep RemoteAnonymousRmit3Enabled" >> /dev/null + + result2=$? + + if [ $result1 == 0 ] && [ $result2 == 0 ]; then + echo "true" + else + echo "false" + fi +} + + +function generateCustomHostNameVerifier() +{ + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME} + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/test/java + cp ${BASE_DIR}/generateCustomHostNameVerifier.sh ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh + cp ${BASE_DIR}/WebLogicCustomHostNameVerifier.java ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java/WebLogicCustomHostNameVerifier.java + cp ${BASE_DIR}/HostNameValuesTemplate.txt ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java/HostNameValuesTemplate.txt + cp ${BASE_DIR}/WebLogicCustomHostNameVerifierTest.java ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/test/java/WebLogicCustomHostNameVerifierTest.java + chown -R $username:$groupname ${CUSTOM_HOSTNAME_VERIFIER_HOME} + chmod +x ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh + + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh ${wlsAdminHost} ${customDNSNameForAdminServer} ${customDNSNameForAdminServer} ${dnsLabelPrefix} ${wlsDomainName} ${location} ${adminVMNamePrefix} ${globalResourceNameSuffix} false" +} + +function copyCustomHostNameVerifierJarsToWebLogicClasspath() +{ + runuser -l oracle -c "cp ${CUSTOM_HOSTNAME_VERIFIER_HOME}/output/*.jar $oracleHome/wlserver/server/lib/;" + + echo "Modify WLS CLASSPATH to include hostname verifier jars...." + sed -i 's;^WEBLOGIC_CLASSPATH="${WL_HOME}/server/lib/postgresql.*;&\nWEBLOGIC_CLASSPATH="${WL_HOME}/server/lib/hostnamevalues.jar:${WL_HOME}/server/lib/weblogicustomhostnameverifier.jar:${WEBLOGIC_CLASSPATH}";' $oracleHome/oracle_common/common/bin/commExtEnv.sh + echo "Modified WLS CLASSPATH to include hostname verifier jars." +} + + +function configureCustomHostNameVerifier() +{ + echo "configureCustomHostNameVerifier for domain $wlsDomainName for server $wlsServerName" + cat <$DOMAIN_PATH/configureCustomHostNameVerifier.py +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') +try: + edit("$wlsServerName") + startEdit() + + cd('/Servers/$wlsServerName/SSL/$wlsServerName') + cmo.setHostnameVerifier('com.oracle.azure.weblogic.security.util.WebLogicCustomHostNameVerifier') + cmo.setHostnameVerificationIgnored(false) + cmo.setTwoWaySSLEnabled(false) + cmo.setClientCertificateEnforced(false) + + save() + activate() +except Exception,e: + print e + print "Failed to configureCustomHostNameVerifier for domain $wlsDomainName" + dumpStack() + raise Exception('Failed to configureCustomHostNameVerifier for domain $wlsDomainName') +disconnect() +EOF +sudo chown -R $username:$groupname $DOMAIN_PATH +runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST $DOMAIN_PATH/configureCustomHostNameVerifier.py" +if [[ $? != 0 ]]; then + echo "Error : Failed to configureCustomHostNameVerifier for domain $wlsDomainName" + exit 1 +fi + +} + +function restartAdminServer() +{ + echo "Stopping WebLogic Admin Server..." + systemctl stop wls_admin + sleep 2m + systemctl start wls_admin + echo "Starting WebLogic Admin Server..." +} + +function packDomain() +{ + echo "Stopping WebLogic nodemanager ..." + sudo systemctl stop wls_nodemanager + echo "Stopping WebLogic Admin Server..." + sudo systemctl stop wls_admin + sleep 2m + echo "Packing the cluster domain" + runuser -l oracle -c "$oracleHome/oracle_common/common/bin/pack.sh -domain=${DOMAIN_PATH}/${wlsDomainName} -template=${mountpointPath}/${wlsDomainName}-template.jar -template_name=\"${wlsDomainName} domain\" -template_desc=\"WebLogic cluster domain\" -managed=true" + if [[ $? != 0 ]]; then + echo "Error : Failed to pack the domain $wlsDomainName" + exit 1 + fi + echo "Starting WebLogic nodemanager ..." + sudo systemctl start wls_nodemanager + echo "Starting WebLogic Admin Server..." + sudo systemctl start wls_admin + touch ${mountpointPath}/${wlsDomainName}-pack.complete +} + +function unpackDomain() +{ + echo "Unpacking the domain" + runuser -l oracle -c "$oracleHome/oracle_common/common/bin/unpack.sh -template=${mountpointPath}/${wlsDomainName}-template.jar -domain=${DOMAIN_PATH}/${wlsDomainName}" + if [[ $? != 0 ]]; then + echo "Error : Failed to unpack the domain $wlsDomainName" + exit 1 + fi +} + #main script starts here CURR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" BASE_DIR="$(readlink -f ${CURR_DIR})" +# Used for certificate expiry validation +CURRENT_DATE=`date +%s` +# Supplied certificate to have minimum days validity for the deployment +# In this case set for 1 day +MIN_CERT_VALIDITY="1" + #read arguments from stdin -read wlsDomainName wlsUserName wlsPassword wlsServerName wlsAdminHost oracleHome storageAccountName storageAccountKey mountpointPath isHTTPAdminListenPortEnabled isCustomSSLEnabled customIdentityKeyStoreData customIdentityKeyStorePassPhrase customIdentityKeyStoreType customTrustKeyStoreData customTrustKeyStorePassPhrase customTrustKeyStoreType serverPrivateKeyAlias serverPrivateKeyPassPhrase +read wlsDomainName wlsUserName wlsShibboleth wlsServerName wlsAdminHost adminVMNamePrefix globalResourceNameSuffix numberOfInstances managedVMPrefix managedServerPrefix oracleHome storageAccountName storageAccountKey mountpointPath isHTTPAdminListenPortEnabled isCustomSSLEnabled customDNSNameForAdminServer dnsLabelPrefix location virtualNetworkNewOrExisting storageAccountPrivateIp customIdentityKeyStoreData customIdentityKeyStorePassPhrase customIdentityKeyStoreType customTrustKeyStoreData customTrustKeyStorePassPhrase customTrustKeyStoreType serverPrivateKeyAlias serverPrivateKeyPassPhrase isHTTPAdminListenPortEnabled="${isHTTPAdminListenPortEnabled,,}" isCustomSSLEnabled="${isCustomSSLEnabled,,}" @@ -761,13 +1018,16 @@ wlsAdminT3ChannelPort=7005 wlsManagedPort=8001 DOMAIN_PATH="/u01/domains" +CUSTOM_HOSTNAME_VERIFIER_HOME="/u01/app/custom-hostname-verifier" startWebLogicScript="${DOMAIN_PATH}/${wlsDomainName}/startWebLogic.sh" stopWebLogicScript="${DOMAIN_PATH}/${wlsDomainName}/bin/customStopWebLogic.sh" +SERVER_STARTUP_ARGS="-Dlog4j2.formatMsgNoLookups=true" wlsAdminURL="$wlsAdminHost:$wlsAdminT3ChannelPort" SERVER_START_URL="http://$wlsAdminURL" -KEYSTORE_PATH="${DOMAIN_PATH}/${wlsDomainName}/keystores" +# Unpack requires domain directory to be empty, hence creating outside the domain +KEYSTORE_PATH="${DOMAIN_PATH}/keystores" if [ "${isCustomSSLEnabled}" == "true" ]; then @@ -787,6 +1047,9 @@ groupname="oracle" cleanup +# Executing this function first just to make sure certificate errors are first caught +storeCustomSSLCerts + installUtilities mountFileShare @@ -797,16 +1060,39 @@ then createStopWebLogicScript create_nodemanager_service admin_boot_setup + generateCustomHostNameVerifier + copyCustomHostNameVerifierJarsToWebLogicClasspath + setUMaskForSecurityDir create_adminserver_service enabledAndStartNodeManagerService enableAndStartAdminServerService wait_for_admin + configureCustomHostNameVerifier + # Create managed server configuration counting from 1 to number of instances + countManagedServer=1 + while [ $countManagedServer -lt $numberOfInstances ] + do + managedServerHost=${managedVMPrefix}${countManagedServer} + wlsServerName=${managedServerPrefix}${countManagedServer} + echo "Configuring managed server ${wlsServerName} for host ${managedServerHost}" + create_managedSetup + countManagedServer=`expr $countManagedServer + 1` + done + # After domain is created pack the domain and keep it under mountFileShare location + packDomain else + # Wait for admin host pack the domain and place the template under mountFileShare location + wait_for_packaged_template updateNetworkRules "managed" - create_managedSetup + # unpack the domain from the template under mountFileShare location + unpackDomain + generateCustomHostNameVerifier + copyCustomHostNameVerifierJarsToWebLogicClasspath + setUMaskForSecurityDir create_nodemanager_service enabledAndStartNodeManagerService wait_for_admin + configureCustomHostNameVerifier start_managed fi diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/setupCoherence.sh b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/setupCoherence.sh index 09ce6e592..b0d0a369a 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/setupCoherence.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/setupCoherence.sh @@ -40,8 +40,8 @@ function validateInput() { echo_stderr "wlsDomainName is required. " fi - if [[ -z "$wlsUserName" || -z "$wlsPassword" ]]; then - echo_stderr "wlsUserName or wlsPassword is required. " + if [[ -z "$wlsUserName" || -z "$wlsShibboleth" ]]; then + echo_stderr "Weblogic username or password is required. " exit 1 fi @@ -77,30 +77,6 @@ function validateInput() { echo_stderr "enableWebLocalStorage is required. " fi - if [ -z "$enableELK" ]; then - echo_stderr "enableELK is required. " - fi - - if [ -z "$elasticURI" ]; then - echo_stderr "elasticURI is required. " - fi - - if [ -z "$elasticUserName" ]; then - echo_stderr "elasticUserName is required. " - fi - - if [ -z "$elasticPassword" ]; then - echo_stderr "elasticPassword is required. " - fi - - if [ -z "$logsToIntegrate" ]; then - echo_stderr "logsToIntegrate is required. " - fi - - if [ -z "$logIndex" ]; then - echo_stderr "logIndex is required. " - fi - if [ -z "$serverIndex" ]; then echo_stderr "serverIndex is required. " fi @@ -127,6 +103,56 @@ function validateInput() { fi } +# This function verifies whether certificate is valid and not expired +function verifyCertValidity() +{ + KEYSTORE=$1 + PASSWORD=$2 + CURRENT_DATE=$3 + MIN_CERT_VALIDITY=$4 + KEY_STORE_TYPE=$5 + VALIDITY=$(($CURRENT_DATE + ($MIN_CERT_VALIDITY*24*60*60))) + + echo "Verifying $KEYSTORE is valid at least $MIN_CERT_VALIDITY day from the deployment time" + + if [ $VALIDITY -le $CURRENT_DATE ]; + then + echo "Error : Invalid minimum validity days supplied" + exit 1 + fi + + # Check whether KEYSTORE supplied can be opened for reading + # Redirecting as no need to display the contents + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $KEYSTORE -storepass $PASSWORD -storetype $KEY_STORE_TYPE > /dev/null 2>&1" + if [ $? != 0 ]; + then + echo "Error opening the keystore : $KEYSTORE" + exit 1 + fi + + aliasList=`runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $KEYSTORE -storepass $PASSWORD -storetype $KEY_STORE_TYPE | grep Alias" |awk '{print $3}'` + if [[ -z $aliasList ]]; + then + echo "Error : No alias found in supplied certificate" + exit 1 + fi + + for alias in $aliasList + do + VALIDITY_PERIOD=`runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $KEYSTORE -storepass $PASSWORD -storetype $KEY_STORE_TYPE -alias $alias | grep Valid"` + echo "$KEYSTORE is \"$VALIDITY_PERIOD\"" + CERT_UNTIL_DATE=`echo $VALIDITY_PERIOD | awk -F'until:|\r' '{print $2}'` + CERT_UNTIL_SECONDS=`date -d "$CERT_UNTIL_DATE" +%s` + VALIDITY_REMIANS_SECONDS=`expr $CERT_UNTIL_SECONDS - $VALIDITY` + if [[ $VALIDITY_REMIANS_SECONDS -le 0 ]]; + then + echo "Error : Supplied certificate is either expired or expiring soon within $MIN_CERT_VALIDITY day" + exit 1 + fi + done + echo "$KEYSTORE validation is successful" +} + #run on admin server #create coherence cluster #associate cluster1 with the coherence cluster @@ -134,12 +160,13 @@ function validateInput() { #associate storage1 with the coherence cluster function createCoherenceCluster() { cat <$wlsDomainPath/configure-coherence-cluster.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') try: edit() - startEdit() + startEdit(60000,60000,'true') cd('/') cmo.createCoherenceClusterSystemResource('${coherenceClusterName}') + Thread.sleep(100) cd('/CoherenceClusterSystemResources/${coherenceClusterName}/CoherenceClusterResource/${coherenceClusterName}/CoherenceClusterParams/${coherenceClusterName}') cmo.setClusteringMode('unicast') @@ -147,6 +174,7 @@ try: cd('/') cmo.createCluster('${storageClusterName}') + Thread.sleep(100) cd('/Clusters/${storageClusterName}') cmo.setClusterMessagingMode('unicast') @@ -169,6 +197,8 @@ try: save() activate() except: + print e + dumpStack() stopEdit('y') sys.exit(1) @@ -189,14 +219,14 @@ function create_managed_model() { cat <$wlsDomainPath/managed-domain.yaml domainInfo: AdminUserName: "$wlsUserName" - AdminPassword: "$wlsPassword" + AdminPassword: "$wlsShibboleth" ServerStartMode: prod topology: Name: "$wlsDomainName" Machine: - '$nmHost': + '$managedServerHost': NodeManager: - ListenAddress: "$nmHost" + ListenAddress: "$managedServerHost" ListenPort: $nmPort NMType : ssl Cluster: @@ -204,10 +234,13 @@ topology: MigrationBasis: 'database' Server: '$wlsServerName' : + ListenAddress: "$managedServerHost" ListenPort: $storageListenPort Notes: "$wlsServerName managed server" Cluster: "$storageClusterName" - Machine: "$nmHost" + Machine: "$managedServerHost" + ServerStart: + Arguments: '${SERVER_STARTUP_ARGS} -Dweblogic.Name=$wlsServerName -Dweblogic.management.server=http://$wlsAdminURL ${wlsCoherenceArgs}' EOF if [ "${isCustomSSLEnabled}" == "true" ]; @@ -240,7 +273,7 @@ EOF cat <>$wlsDomainPath/managed-domain.yaml SecurityConfiguration: NodeManagerUsername: "$wlsUserName" - NodeManagerPasswordEncrypted: "$wlsPassword" + NodeManagerPasswordEncrypted: "$wlsShibboleth" EOF } @@ -248,11 +281,12 @@ EOF function create_machine_model() { echo "Creating machine name model for managed server $wlsServerName" cat <$wlsDomainPath/add-machine.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') edit("$wlsServerName") -startEdit() +startEdit(60000,60000,'true') cd('/') cmo.createMachine('$nmHost') +Thread.sleep(100) cd('/Machines/$nmHost/NodeManager/$nmHost') cmo.setListenPort(int($nmPort)) cmo.setListenAddress('$nmHost') @@ -271,11 +305,12 @@ function create_ms_server_model() { cat <$wlsDomainPath/add-server.py isCustomSSLEnabled='${isCustomSSLEnabled}' -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') edit("$wlsServerName") -startEdit() +startEdit(60000,60000,'true') cd('/') cmo.createServer('$wlsServerName') +Thread.sleep(100) cd('/Servers/$wlsServerName') cmo.setMachine(getMBean('/Machines/$nmHost')) cmo.setCluster(getMBean('/Clusters/$storageClusterName')) @@ -298,8 +333,13 @@ set('ServerPrivateKeyPassPhrase', '$serverPrivateKeyPassPhrase') cmo.setHostnameVerificationIgnored(true) cd('/Servers/$wlsServerName/ServerStart/$wlsServerName') -arguments = '-Dweblogic.Name=$wlsServerName -Dweblogic.security.SSL.ignoreHostnameVerification=true -Dweblogic.management.server=http://$wlsAdminURL ${wlsCoherenceArgs}' -cmo.setArguments(arguments) +arguments = '${SERVER_STARTUP_ARGS} -Dweblogic.Name=$wlsServerName -Dweblogic.management.server=http://$wlsAdminURL ${wlsCoherenceArgs}' +oldArgs = cmo.getArguments() +if oldArgs != None: + newArgs = oldArgs + ' ' + arguments +else: + newArgs = arguments +cmo.setArguments(newArgs) save() resolve() activate() @@ -369,9 +409,10 @@ Wants=network-online.target Type=simple # Note that the following three parameters should be changed to the correct paths # on your own system -WorkingDirectory="$wlsDomainPath/$wlsDomainName" -ExecStart="$wlsDomainPath/$wlsDomainName/bin/startNodeManager.sh" -ExecStop="$wlsDomainPath/$wlsDomainName/bin/stopNodeManager.sh" +WorkingDirectory=/u01/domains +Environment="JAVA_OPTIONS=${SERVER_STARTUP_ARGS}" +ExecStart=/bin/bash $wlsDomainPath/$wlsDomainName/bin/startNodeManager.sh +ExecStop=/bin/bash $wlsDomainPath/$wlsDomainName/bin/stopNodeManager.sh User=oracle Group=oracle KillMode=process @@ -388,7 +429,7 @@ EOF function startManagedServer() { echo "Starting managed server $wlsServerName" cat <$wlsDomainPath/start-server.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') try: start('$wlsServerName', 'Server') except: @@ -407,11 +448,11 @@ EOF function restartManagedServers() { echo "Restart managed servers" cat <$wlsDomainPath/restart-managedServer.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') servers=cmo.getServers() try: - edit("$nmHost") - startEdit() + edit("$managedServerHost") + startEdit(60000,60000,'true') for server in servers: if (server.getCluster()!=None and server.getCluster().getName()=='${clientClusterName}'): cd('/Servers/'+server.getName()+'//ServerStart/'+server.getName()) @@ -425,7 +466,7 @@ except Exception, e: dumpStack() undo('true',defaultAnswer='y') cancelEdit('y') - destroyEditSession("$nmHost",force = true) + destroyEditSession("$managedServerHost",force = true) raise("Set coherence port range failed") domainRuntime() @@ -458,40 +499,48 @@ EOF function createManagedSetup() { echo "Creating Managed Server Setup" cd $wlsDomainPath - wget -q $weblogicDeployTool - if [[ $? != 0 ]]; then - echo "Error : Downloading weblogic-deploy-tool failed" + + # WebLogic base images are already having weblogic-deploy, hence no need to download + if [ ! -d "$wlsDomainPath/weblogic-deploy" ]; + then + echo "weblogic-deploy tool not found in path $wlsDomainPath" exit 1 fi - sudo unzip -o weblogic-deploy.zip -d $wlsDomainPath + echo "Creating managed server model files" create_managed_model - create_machine_model - create_ms_server_model + # Following are not requires as it is taken care by create_managed_model applied on existing domain + #create_machine_model + #create_ms_server_model echo "Completed managed server model files" sudo chown -R $username:$groupname $wlsDomainPath - runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; $wlsDomainPath/weblogic-deploy/bin/createDomain.sh -oracle_home $oracleHome -domain_parent $wlsDomainPath -domain_type WLS -model_file $wlsDomainPath/managed-domain.yaml" + adminWlstURL="t3://$wlsAdminURL" + # Updating managed-domain.yaml using updateDomain.sh on existing domain created by create_admin_model + # wlsShibboleth is accepted from stdin to support old and new weblogic-deploy tool version + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; $wlsDomainPath/weblogic-deploy/bin/updateDomain.sh -admin_url $adminWlstURL -admin_user $wlsUserName -oracle_home $oracleHome -domain_home $DOMAIN_PATH/${wlsDomainName} -domain_type WLS -model_file $wlsDomainPath/managed-domain.yaml <<< $wlsShibboleth" if [[ $? != 0 ]]; then echo "Error : Managed setup failed" exit 1 fi - wait_for_admin - - # For issue https://github.com/wls-eng/arm-oraclelinux-wls/issues/89 - getSerializedSystemIniFileFromShare - - echo "Adding machine to managed server $wlsServerName" - runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST $wlsDomainPath/add-machine.py" - if [[ $? != 0 ]]; then - echo "Error : Adding machine for managed server $wlsServerName failed" - exit 1 - fi - echo "Adding managed server $wlsServerName" - runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST $wlsDomainPath/add-server.py" - if [[ $? != 0 ]]; then - echo "Error : Adding server $wlsServerName failed" - exit 1 - fi + + # Following are not required as updateDomain.sh with managed-domain.yaml will take care of following + #wait_for_admin + + ## For issue https://github.com/wls-eng/arm-oraclelinux-wls/issues/89 + #getSerializedSystemIniFileFromShare + + #echo "Adding machine to managed server $wlsServerName" + #runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST $wlsDomainPath/add-machine.py" + #if [[ $? != 0 ]]; then + #echo "Error : Adding machine for managed server $wlsServerName failed" + #exit 1 + #fi + #echo "Adding managed server $wlsServerName" + #runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST $wlsDomainPath/add-server.py" + #if [[ $? != 0 ]]; then + #echo "Error : Adding server $wlsServerName failed" + #exit 1 + #fi } function enabledAndStartNodeManagerService() { @@ -511,15 +560,71 @@ function enabledAndStartNodeManagerService() { done } +#This function to wait for packaged domain availability at ${mountpointPath} by checking ${wlsDomainName}-pack.complete +function wait_for_packaged_template() +{ + #wait for packaged domain template to be available + count=1 + echo "Waiting for packaged domain template availability ${mountpointPath}/${wlsDomainName}-template.jar" + while [ ! -f ${mountpointPath}/${wlsDomainName}-pack.complete ] + do + echo "." + count=$((count+1)) + if [ $count -le 30 ]; + then + sleep 1m + else + echo "Error : Maximum attempts exceeded for waiting packaged domain template ${mountpointPath}/${wlsDomainName}-template.jar" + exit 1 + fi + done +} + +function packDomain() +{ + echo "Stopping WebLogic nodemanager ..." + sudo systemctl stop wls_nodemanager + echo "Stopping WebLogic Admin Server..." + sudo systemctl stop wls_admin + sleep 2m + echo "Packing the cluster domain" + runuser -l oracle -c "$oracleHome/oracle_common/common/bin/pack.sh -domain=${DOMAIN_PATH}/${wlsDomainName} -template=${mountpointPath}/${wlsDomainName}-template.jar -template_name=\"${wlsDomainName} domain\" -template_desc=\"WebLogic cluster domain\" -managed=true" + if [[ $? != 0 ]]; then + echo "Error : Failed to pack the domain $wlsDomainName" + exit 1 + fi + echo "Starting WebLogic nodemanager ..." + sudo systemctl start wls_nodemanager + echo "Starting WebLogic Admin Server..." + sudo systemctl start wls_admin + wait_for_admin + touch ${mountpointPath}/${wlsDomainName}-pack.complete +} + +function unpackDomain() +{ + echo "Unpacking the domain" + runuser -l oracle -c "$oracleHome/oracle_common/common/bin/unpack.sh -template=${mountpointPath}/${wlsDomainName}-template.jar -domain=${DOMAIN_PATH}/${wlsDomainName}" + if [[ $? != 0 ]]; then + echo "Error : Failed to unpack the domain $wlsDomainName" + exit 1 + fi +} + function cleanup() { echo "Cleaning up temporary files..." rm -rf $wlsDomainPath/managed-domain.yaml - rm -rf $wlsDomainPath/weblogic-deploy.zip - rm -rf $wlsDomainPath/weblogic-deploy rm -rf $wlsDomainPath/*.py + rm -rf ${CUSTOM_HOSTNAME_VERIFIER_HOME} echo "Cleanup completed." } +function cleanupTemplates() { + # This has to be deleted as pack command doesn't overwrite. Also managed server unpack shouldn't start before pack domain is completed + rm -f ${mountpointPath}/${wlsDomainName}-pack.complete + rm -f ${mountpointPath}/${wlsDomainName}-template.jar +} + function openManagedServerPorts() { # for Oracle Linux 7.3, 7.4, iptable is not running. if [ -z $(command -v firewall-cmd) ]; then @@ -559,8 +664,8 @@ function mountFileShare() { fi echo "chmod 600 /etc/smbcredentials/${storageAccountName}.cred" sudo chmod 600 /etc/smbcredentials/${storageAccountName}.cred - echo "//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred ,dir_mode=0777,file_mode=0777,serverino" - sudo bash -c "echo \"//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred ,dir_mode=0777,file_mode=0777,serverino\" >> /etc/fstab" + echo "//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino" + sudo bash -c "echo \"//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino\" >> /etc/fstab" echo "mount -t cifs //${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino" sudo mount -t cifs //${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino if [[ $? != 0 ]]; then @@ -593,6 +698,9 @@ function validateSSLKeyStores() exit 1 fi + # Verify Identity keystore validity period more than MIN_CERT_VALIDITY + verifyCertValidity $customIdentityKeyStoreFileName $customIdentityKeyStorePassPhrase $CURRENT_DATE $MIN_CERT_VALIDITY $customIdentityKeyStoreType + #validate Trust keystore runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $customTrustKeyStoreFileName -storepass $customTrustKeyStorePassPhrase -storetype $customTrustKeyStoreType | grep 'Entry type:' | grep 'trustedCertEntry'" @@ -600,7 +708,10 @@ function validateSSLKeyStores() echo "Error : Trust Keystore Validation Failed !!" exit 1 fi - + + # Verify Identity keystore validity period more than MIN_CERT_VALIDITY + verifyCertValidity $customTrustKeyStoreFileName $customTrustKeyStorePassPhrase $CURRENT_DATE $MIN_CERT_VALIDITY $customTrustKeyStoreType + echo "ValidateSSLKeyStores Successfull !!" } @@ -615,21 +726,23 @@ function storeCustomSSLCerts() customIdentityKeyStoreFileName="$KEYSTORE_PATH/identity.keystore" customTrustKeyStoreFileName="$KEYSTORE_PATH/trust.keystore" + if [ "${addnodeFlag}" == "false" ]; + then + echo "decode cert data once again as it would get base64 encoded while storing in azure keyvault" customIdentityKeyStoreData=$(echo "$customIdentityKeyStoreData" | base64 --decode) + customTrustKeyStoreData=$(echo "$customTrustKeyStoreData" | base64 --decode) + fi + + echo "$customIdentityKeyStoreData" | base64 --decode > $customIdentityKeyStoreFileName + echo "$customTrustKeyStoreData" | base64 --decode > $customTrustKeyStoreFileName + customIdentityKeyStorePassPhrase=$(echo "$customIdentityKeyStorePassPhrase" | base64 --decode) customIdentityKeyStoreType=$(echo "$customIdentityKeyStoreType" | base64 --decode) - - customTrustKeyStoreData=$(echo "$customTrustKeyStoreData" | base64 --decode) customTrustKeyStorePassPhrase=$(echo "$customTrustKeyStorePassPhrase" | base64 --decode) customTrustKeyStoreType=$(echo "$customTrustKeyStoreType" | base64 --decode) - serverPrivateKeyAlias=$(echo "$serverPrivateKeyAlias" | base64 --decode) serverPrivateKeyPassPhrase=$(echo "$serverPrivateKeyPassPhrase" | base64 --decode) - #decode cert data once again as it would got base64 encoded while storing in azure keyvault - echo "$customIdentityKeyStoreData" | base64 --decode > $customIdentityKeyStoreFileName - echo "$customTrustKeyStoreData" | base64 --decode > $customTrustKeyStoreFileName - validateSSLKeyStores else @@ -637,11 +750,76 @@ function storeCustomSSLCerts() fi } +function generateCustomHostNameVerifier() +{ + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME} + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/test/java + cp ${BASE_DIR}/generateCustomHostNameVerifier.sh ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh + cp ${BASE_DIR}/WebLogicCustomHostNameVerifier.java ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java/WebLogicCustomHostNameVerifier.java + cp ${BASE_DIR}/HostNameValuesTemplate.txt ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java/HostNameValuesTemplate.txt + cp ${BASE_DIR}/WebLogicCustomHostNameVerifierTest.java ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/test/java/WebLogicCustomHostNameVerifierTest.java + chown -R $username:$groupname ${CUSTOM_HOSTNAME_VERIFIER_HOME} + chmod +x ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh + + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh ${adminVMName} ${customDNSNameForAdminServer} ${customDNSNameForAdminServer} ${dnsLabelPrefix} ${wlsDomainName} ${location} ${adminVMNamePrefix} ${globalResourceNameSuffix} false" +} + +function copyCustomHostNameVerifierJarsToWebLogicClasspath() +{ + runuser -l oracle -c "cp ${CUSTOM_HOSTNAME_VERIFIER_HOME}/output/*.jar $oracleHome/wlserver/server/lib/;" + + echo "Modify WLS CLASSPATH to include hostname verifier jars...." + sed -i 's;^WEBLOGIC_CLASSPATH="${WL_HOME}/server/lib/postgresql.*;&\nWEBLOGIC_CLASSPATH="${WL_HOME}/server/lib/hostnamevalues.jar:${WL_HOME}/server/lib/weblogicustomhostnameverifier.jar:${WEBLOGIC_CLASSPATH}";' $oracleHome/oracle_common/common/bin/commExtEnv.sh + echo "Modified WLS CLASSPATH to include hostname verifier jars." +} + + +function configureCustomHostNameVerifier() +{ + echo "configureCustomHostNameVerifier for domain $wlsDomainName for server $wlsServerName" + cat <$DOMAIN_PATH/configureCustomHostNameVerifier.py +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') +try: + edit("$wlsServerName") + startEdit() + + cd('/Servers/$wlsServerName/SSL/$wlsServerName') + cmo.setHostnameVerifier('com.oracle.azure.weblogic.security.util.WebLogicCustomHostNameVerifier') + cmo.setHostnameVerificationIgnored(false) + cmo.setTwoWaySSLEnabled(false) + cmo.setClientCertificateEnforced(false) + + save() + activate() +except Exception,e: + print e + print "Failed to configureCustomHostNameVerifier for domain $wlsDomainName" + dumpStack() + raise Exception('Failed to configureCustomHostNameVerifier for domain $wlsDomainName') +disconnect() +EOF +sudo chown -R $username:$groupname $DOMAIN_PATH +runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST $DOMAIN_PATH/configureCustomHostNameVerifier.py" +if [[ $? != 0 ]]; then + echo "Error : Failed to configureCustomHostNameVerifier for domain $wlsDomainName" + exit 1 +fi + +} + # main script starts from here SCRIPT_PWD=$(pwd) +CURR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +BASE_DIR="$(readlink -f ${CURR_DIR})" + +# Used for certificate expiry validation +CURRENT_DATE=`date +%s` +# Supplied certificate to have minimum days validity for the deployment +MIN_CERT_VALIDITY="1" -read wlsDomainName wlsUserName wlsPassword adminVMName oracleHome wlsDomainPath storageAccountName storageAccountKey mountpointPath enableWebLocalStorage enableELK elasticURI elasticUserName elasticPassword logsToIntegrate logIndex managedServerPrefix serverIndex isCustomSSLEnabled customIdentityKeyStoreData customIdentityKeyStorePassPhrase customIdentityKeyStoreType customTrustKeyStoreData customTrustKeyStorePassPhrase customTrustKeyStoreType serverPrivateKeyAlias serverPrivateKeyPassPhrase +read wlsDomainName wlsUserName wlsShibboleth adminVMName adminVMNamePrefix globalResourceNameSuffix numberOfCoherenceCacheInstances managedVMPrefix oracleHome wlsDomainPath storageAccountName storageAccountKey mountpointPath enableWebLocalStorage managedServerPrefix serverIndex customDNSNameForAdminServer dnsLabelPrefix location addnodeFlag isCustomSSLEnabled customIdentityKeyStoreData customIdentityKeyStorePassPhrase customIdentityKeyStoreType customTrustKeyStoreData customTrustKeyStorePassPhrase customTrustKeyStoreType serverPrivateKeyAlias serverPrivateKeyPassPhrase isCustomSSLEnabled="${isCustomSSLEnabled,,}" @@ -650,6 +828,7 @@ then isCustomSSLEnabled="false" fi +DOMAIN_PATH="/u01/domains" wlsAdminT3ChannelPort=7005 wlsAdminURL="${adminVMName}:${wlsAdminT3ChannelPort}" coherenceClusterName="myCoherence" @@ -657,16 +836,25 @@ coherenceListenPort=7574 coherenceLocalport=42000 coherenceLocalportAdjust=42200 clientClusterName="cluster1" +CUSTOM_HOSTNAME_VERIFIER_HOME="/u01/app/custom-hostname-verifier" groupname="oracle" +thisHost=$(hostname) nmHost=$(hostname) nmPort=5556 storageClusterName="storage1" storageListenPort=7501 -weblogicDeployTool=https://github.com/oracle/weblogic-deploy-tooling/releases/download/weblogic-deploy-tooling-1.8.1/weblogic-deploy.zip username="oracle" wlsAdminServerName="admin" wlsCoherenceArgs="-Dcoherence.localport=$coherenceLocalport -Dcoherence.localport.adjust=$coherenceLocalportAdjust" -KEYSTORE_PATH="${wlsDomainPath}/${wlsDomainName}/keystores" +KEYSTORE_PATH="${DOMAIN_PATH}/keystores" +SERVER_STARTUP_ARGS="-Dlog4j2.formatMsgNoLookups=true" + +if [ -z "$addnodeFlag" ]; +then + addnodeFlag="false" +fi + +addnodeFlag="${addnodeFlag,,}" if [ ${serverIndex} -eq 0 ]; then wlsServerName="admin" @@ -677,39 +865,36 @@ fi validateInput cleanup +# Executing this function first just to make sure certificate errors are first caught +storeCustomSSLCerts + if [ "$wlsServerName" == "${wlsAdminServerName}" ]; then + cleanupTemplates createCoherenceCluster restartManagedServers + countManagedServer=1 + while [ $countManagedServer -le $numberOfCoherenceCacheInstances ] + do + managedServerHost=${managedVMPrefix}${countManagedServer} + wlsServerName=${managedServerPrefix}${countManagedServer} + echo "Configuring managed server ${wlsServerName} for host ${managedServerHost}" + createManagedSetup + countManagedServer=`expr $countManagedServer + 1` + done + packDomain else installUtilities mountFileShare openManagedServerPorts - storeCustomSSLCerts - createManagedSetup + wait_for_packaged_template + unpackDomain + generateCustomHostNameVerifier + copyCustomHostNameVerifierJarsToWebLogicClasspath createNodeManagerService enabledAndStartNodeManagerService - startManagedServer - - echo "enable ELK? ${enableELK}" - chmod ugo+x ${SCRIPT_PWD}/elkIntegration.sh - if [[ "${enableELK,,}" == "true" ]]; then - echo "Set up ELK..." - ${SCRIPT_PWD}/elkIntegration.sh \ - ${oracleHome} \ - ${wlsAdminURL} \ - ${wlsUserName} \ - ${wlsPassword} \ - "admin" \ - ${elasticURI} \ - ${elasticUserName} \ - ${elasticPassword} \ - ${wlsDomainName} \ - ${wlsDomainPath}/${wlsDomainName} \ - ${logsToIntegrate} \ - ${serverIndex} \ - ${logIndex} \ - ${managedServerPrefix} - fi + wait_for_admin + configureCustomHostNameVerifier + startManagedServer fi cleanup diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/updateDNSZones.sh b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/updateDNSZones.sh index 80b387aec..78f21e8a2 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/updateDNSZones.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/arm-oraclelinux-wls-cluster/src/main/scripts/updateDNSZones.sh @@ -1,42 +1,44 @@ #!/bin/bash - # Copyright (c) 2021, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + # Description -# This script is to configure DNS zones during Azure deployment. - -resourceGroup=$1 -zoneName=$2 -recordSetNames=$3 -targetResources=$4 -lenRecordset=$5 -lenTargets=$6 -ttl=${7} -cnameRecordSetNames=${8} -cnameAlias=${9} -lenCnameRecordSetNames=${10} -lenCnameAlias=${11} - -if [[ ${lenRecordset} != ${lenTargets} ]]; then +# This script updates the Azure DNS Zones used for configuring DNS for WebLogic Admin Server and Azure Application Gateway. + +# Inputs: +# RESOURCE_GROUP_NAME +# DNS_ZONE_NAME +# DNS_RECORDSET_NAMES +# DNS_TARGET_RESOURCES +# DNS_RECORD_NAMES_LENGTH +# DNS_TARGET_RESOURCES_LENGTH +# DNS_RECORD_TTL +# DNS_CNAME_RECORDSET_NAMES +# DNS_CNAME_ALIAS +# DNS_CNAME_RECORDSET_LENGTH +# DNS_CNAME_ALIAS_LENGTH +# MANAGED_IDENTITY_ID + +if [[ ${DNS_RECORD_NAMES_LENGTH} != ${DNS_TARGET_RESOURCES_LENGTH} ]]; then echo "Error: number of A record set names is not equal to that of target resources." exit 1 fi -if [[ ${lenCnameRecordSetNames} != ${lenCnameAlias} ]]; then +if [[ ${DNS_CNAME_RECORDSET_LENGTH} != ${DNS_CNAME_ALIAS_LENGTH} ]]; then echo "Error: number of CNAME record set names is not equal to that of alias." exit 1 fi # check if the zone exist -az network dns zone show -g ${resourceGroup} -n ${zoneName} +az network dns zone show -g ${RESOURCE_GROUP_NAME} -n ${DNS_ZONE_NAME} # query name server for testing -nsforTest=$(az network dns record-set ns show -g ${resourceGroup} -z ${zoneName} -n @ --query "nsRecords"[0].nsdname -o tsv) +nsforTest=$(az network dns record-set ns show -g ${RESOURCE_GROUP_NAME} -z ${DNS_ZONE_NAME} -n @ --query "nsRecords"[0].nsdname -o tsv) echo name server: ${nsforTest} -if [ ${lenRecordset} -gt 0 ]; then - recordSetNamesArr=$(echo $recordSetNames | tr "," "\n") - targetResourcesArr=$(echo $targetResources | tr "," "\n") +if [ ${DNS_RECORD_NAMES_LENGTH} -gt 0 ]; then + recordSetNamesArr=$(echo $DNS_RECORDSET_NAMES | tr "," "\n") + targetResourcesArr=$(echo $DNS_TARGET_RESOURCES | tr "," "\n") index=0 for record in $recordSetNamesArr; do @@ -45,13 +47,13 @@ if [ ${lenRecordset} -gt 0 ]; then if [ $count -eq $index ]; then echo Create A record with name: $record, target IP: $target az network dns record-set a create \ - -g ${resourceGroup} \ - -z ${zoneName} \ + -g ${RESOURCE_GROUP_NAME} \ + -z ${DNS_ZONE_NAME} \ -n ${record} \ --target-resource ${target} \ - --ttl ${ttl} + --ttl ${DNS_RECORD_TTL} - nslookup ${record}.${zoneName} ${nsforTest} + nslookup ${record}.${DNS_ZONE_NAME} ${nsforTest} if [ $? -eq 1 ];then echo Error: failed to create record with name: $record, target Id: $target exit 1 @@ -65,9 +67,9 @@ if [ ${lenRecordset} -gt 0 ]; then done fi -if [ ${lenCnameRecordSetNames} -gt 0 ];then - cnameRecordSetArr=$(echo $cnameRecordSetNames | tr "," "\n") - cnameRecordAliasArr=$(echo $cnameAlias | tr "," "\n") +if [ ${DNS_CNAME_RECORDSET_LENGTH} -gt 0 ];then + cnameRecordSetArr=$(echo $DNS_CNAME_RECORDSET_NAMES | tr "," "\n") + cnameRecordAliasArr=$(echo $DNS_CNAME_ALIAS | tr "," "\n") index=0 for record in $cnameRecordSetArr; do @@ -76,18 +78,18 @@ if [ ${lenCnameRecordSetNames} -gt 0 ];then if [ $count -eq $index ]; then echo Create CNAME record with name: $record, alias: $target az network dns record-set cname create \ - -g ${resourceGroup} \ - -z ${zoneName} \ + -g ${RESOURCE_GROUP_NAME} \ + -z ${DNS_ZONE_NAME} \ -n ${record} \ - --ttl ${ttl} + --ttl ${DNS_RECORD_TTL} az network dns record-set cname set-record \ - -g ${resourceGroup} \ - -z ${zoneName} \ + -g ${RESOURCE_GROUP_NAME} \ + -z ${DNS_ZONE_NAME} \ --cname ${target} \ --record-set-name ${record} - nslookup ${record}.${zoneName} ${nsforTest} + nslookup ${record}.${DNS_ZONE_NAME} ${nsforTest} if [ $? -eq 1 ];then echo Error: failed to create CNAME record with name: $record, alia: $target exit 1 @@ -100,3 +102,7 @@ if [ ${lenCnameRecordSetNames} -gt 0 ];then index=$((index + 1)) done fi + +# delete user assigned managed identity + +az identity delete --ids ${MANAGED_IDENTITY_ID} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/cli-scripts/custom-dns-alias-cli.sh b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/cli-scripts/custom-dns-alias-cli.sh index 368744be0..ca0968fd3 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/cli-scripts/custom-dns-alias-cli.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/cli-scripts/custom-dns-alias-cli.sh @@ -22,7 +22,6 @@ Options: -l --location (Required) Location of current cluster resources. -z --zone-name (Required) DNS Zone name --gateway-label (Optional) Specify a lable to generate the DNS alias for Application Gateway - --identity-id (Optional) Specify an Azure Managed User Identity to update DNS Zone --zone-resource-group (Optional) The name of resource group that has WebLogic cluster deployed -h --help @@ -36,7 +35,6 @@ Samples: --location eastus \\ --zone-name contoso.com \\ --gateway-label application \\ - --identity-id \\ --zone-resource-group haiche-dns-test1 2. Configure DNS alias on a new DNS Zone @@ -201,14 +199,6 @@ EOF "hasDNSZones": { "value": ${hasDNSZone} }, - "identity": { - "value": { - "type": "UserAssigned", - "userAssignedIdentities": { - "${identity}": {} - } - } - }, "location": { "value": "${location}" }, @@ -287,7 +277,6 @@ Custom DNS alias: # default value enableGateWay=false hasDNSZone=false -identity=/subscriptions/subscriptionId/resourceGroups/TestResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/TestUserIdentity1 # Transform long options to short ones for arg in "$@"; do @@ -301,7 +290,6 @@ for arg in "$@"; do "--admin-console-label") set -- "$@" "-c" ;; "--gateway-label") set -- "$@" "-w" ;; "--zone-resource-group") set -- "$@" "-r" ;; - "--identity-id") set -- "$@" "-i" ;; "--location") set -- "$@" "-l" ;; "--"*) set -- usage @@ -326,7 +314,6 @@ while getopts "hg:f:z:m:c:w:r:i:l:" opt; do "c") adminLabel="$OPTARG" ;; "w") gatewayLabel="$OPTARG" ;; "r") zoneResourceGroup="$OPTARG" ;; - "i") identity="$OPTARG" ;; "l") location="$OPTARG" ;; esac done diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/deletenode/pom.xml b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/deletenode/pom.xml index 3eed1ca2a..41a7455d0 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/deletenode/pom.xml +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/deletenode/pom.xml @@ -1,38 +1,39 @@ - + 4.0.0 - com.oracle.weblogic.azure - arm-oraclelinux-wls-cluster-deletenode - 1.0.1 - - com.microsoft.azure.iaas - azure-javaee-iaas-parent - 1.0.7 - + com.oracle.weblogic.azure + weblogic-azure-vm + 1.0.0 + ../../pom.xml - + + com.oracle.weblogic.azure + arm-oraclelinux-wls-cluster-deletenode + ${version.arm-oraclelinux-wls-cluster-deletenode} + jar ${project.artifactId} - ${basedir}/../../arm-ttk/arm-ttk - -TestParameter '@{"SampleName"="deletenode/src/main";"RawRepoPath"="${artifactsLocationBase}/arm-oraclelinux-wls-cluster/${git.tag}/"}' - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/pid.properties - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/microsoft-pid.properties + -TestParameter '@{"SampleName"="deletenode/src/main";"RawRepoPath"="${artifactsLocationBase}/arm-oraclelinux-wls-cluster/"}' + ${project.basedir}/../../.. + false + false - + diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/deletenode/src/main/arm/mainTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/deletenode/src/main/arm/mainTemplate.json index 3048c2143..bab15a8b0 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/deletenode/src/main/arm/mainTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/deletenode/src/main/arm/mainTemplate.json @@ -7,7 +7,7 @@ "metadata": { "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." }, - "defaultValue": "${artifactsLocationBase}/arm-oraclelinux-wls-cluster/${git.tag}/deletenode/src/main/" + "defaultValue": "${artifactsLocationBase}/arm-oraclelinux-wls-cluster/deletenode/src/main/" }, "_artifactsLocationSasToken": { "type": "securestring", @@ -69,8 +69,6 @@ "variables": { "const_wlsAdminPort": "7001", "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", - "const_outputCliCommand0": "[concat('export resourceGroup=', resourceGroup().name,';', 'export deleteingIDs=\"\";export managedServerMachineNames=$(echo ',array.join(parameters('deletingManagedServerMachineNames')),' | tr \",\" \"\\n\");','az extension add --name resource-graph;','for machine in $managedServerMachineNames;do vmId=$(az graph query -q \"Resources | where type =~ ','\\','\"microsoft.compute/virtualmachines\\\" | where name=~ \\\"${machine}\\\" | where resourceGroup =~ \\\"${resourceGroup}\\\" | project vmid = id\" -o tsv); nicId=$(az graph query -q \"Resources | where type =~ \\\"microsoft.compute/virtualmachines\\\" | where name=~ \\\"${machine}\\\" | where resourceGroup =~ \\\"${resourceGroup}\\\" | extend nics=array_length(properties.networkProfile.networkInterfaces) | mv-expand nic=properties.networkProfile.networkInterfaces | where nics == 1 or nic.properties.primary =~ \\\"true\\\" or isempty(nic) | project nicId = tostring(nic.id)\" -o tsv);ipId=$(az graph query -q \"Resources | where type =~ \\\"microsoft.network/networkinterfaces\\\" | where id=~ \\\"${nicId}\\\" | extend ipConfigsCount=array_length(properties.ipConfigurations) | mv-expand ipconfig=properties.ipConfigurations | where ipConfigsCount == 1 or ipconfig.properties.primary =~ \\\"true\\\" | project publicIpId = tostring(ipconfig.properties.publicIPAddress.id)\" -o tsv);osDiskId=$(az graph query -q \"Resources | where type =~ \\\"microsoft.compute/virtualmachines\\\" | where name=~ \\\"${machine}\\\" | where resourceGroup =~ \\\"${resourceGroup}\\\" | project osDiskId = tostring(properties.storageProfile.osDisk.managedDisk.id)\" -o tsv);dataDiskIds=$(az graph query -q \"Resources | where type =~ \\\"microsoft.compute/virtualmachines\\\" | where name=~ \\\"${machine}\\\" | where resourceGroup =~ \\\"${resourceGroup}\\\" | mv-expand datadisk=properties.storageProfile.dataDisks | project datadisk.managedDisk.id\" -o tsv);deleteingIDs=$(echo $deleteingIDs ${vmId} ${nicId} ${ipId} ${osDiskId} ${dataDiskIds});done;echo \"List resource Ids to be deleted: \";echo ${deleteingIDs} | tr \" \" \"\\n\";echo -n \"Are you sure to delete these resources (y/n)?\";read answer;if [[ \"$answer\" != \"${answer#[Yy]}\" && -n \"${deleteingIDs}\" ]]; then echo \"Deleting managed resources...Please do not stop.\";az resource delete --verbose --ids ${deleteingIDs};fi')]", - "const_outputCliCommands": "[concat(variables('const_outputCliCommand0'), ';','echo \"Check if application gateway has deployed...\"; appGateway=$(az resource list -g ${resourceGroup} -n myAppGateway --resource-type Microsoft.Network/applicationGateways | grep \"myAppGateway\");if [ -n \"${appGateway}\" ];then for machine in $managedServerMachineNames;do backendAddresses=$(az network application-gateway address-pool list -g ${resourceGroup} --gateway-name myAppGateway --query [0].backendAddresses | grep \"fqdn\"); if [ $? == 0 ]; then beAddArr=$(echo \"$backendAddresses\" | sed \"s/ //g\" | tr \",\" \"\\n\");index=0;len=0;for item in $beAddArr;do ret=$(echo $item | grep \"$machine\");if [ -z \"$ret\" ];then index=$((index+1));len=$((len+1)); else len=$((len+1));break; fi done; if [[ ${index} -lt ${len} ]]; then echo \"Removing $machine from application gateway, please do not stop.\"; az network application-gateway address-pool update -g ${resourceGroup} --gateway-name myAppGateway --name myGatewayBackendPool --remove backendAddresses ${index};fi;fi; done; fi')]", "name_scriptDeleteNode": "deletenode.sh" }, "functions": [ @@ -95,7 +93,7 @@ "resources": [ { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${cluster.deletenode.start}", "properties": { "mode": "Incremental", @@ -108,8 +106,8 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", "name": "[concat(parameters('adminVMName'),'/newuserscript')]", "location": "[parameters('location')]", "properties": { @@ -129,7 +127,7 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${cluster.deletenode.end}", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" @@ -148,7 +146,7 @@ "outputs": { "commandsToDeleteAzureResource": { "type": "string", - "value": "[variables('const_outputCliCommands')]" + "value": "[concat('export resourceGroup=', resourceGroup().name,';', 'export deleteingIDs=\"\";export managedServerMachineNames=$(echo ',array.join(parameters('deletingManagedServerMachineNames')),' | tr \",\" \"\\n\");','az extension add --name resource-graph;','for machine in $managedServerMachineNames;do vmId=$(az graph query -q \"Resources | where type =~ ','\\','\"microsoft.compute/virtualmachines\\\" | where name=~ \\\"${machine}\\\" | where resourceGroup =~ \\\"${resourceGroup}\\\" | project vmid = tolower(id)\" --query data[0].vmid -o tsv); nicId=$(az graph query -q \"Resources | where type =~ \\\"microsoft.compute/virtualmachines\\\" | where name=~ \\\"${machine}\\\" | where resourceGroup =~ \\\"${resourceGroup}\\\" | extend nics=array_length(properties.networkProfile.networkInterfaces) | mv-expand nic=properties.networkProfile.networkInterfaces | where nics == 1 or nic.properties.primary =~ \\\"true\\\" or isempty(nic) | project nicId = tostring(nic.id)\" --query data[0].nicId -o tsv);ipId=$(az graph query -q \"Resources | where type =~ \\\"microsoft.network/networkinterfaces\\\" | where id=~ \\\"${nicId}\\\" | extend ipConfigsCount=array_length(properties.ipConfigurations) | mv-expand ipconfig=properties.ipConfigurations | where ipConfigsCount == 1 or ipconfig.properties.primary =~ \\\"true\\\" | project publicIpId = tostring(ipconfig.properties.publicIPAddress.id)\" --query data[0].publicIpId -o tsv);osDiskId=$(az graph query -q \"Resources | where type =~ \\\"microsoft.compute/virtualmachines\\\" | where name=~ \\\"${machine}\\\" | where resourceGroup =~ \\\"${resourceGroup}\\\" | project osDiskId = tostring(properties.storageProfile.osDisk.managedDisk.id)\" --query data[0].osDiskId -o tsv);deleteingIDs=$(echo $deleteingIDs ${vmId} ${nicId} ${ipId} ${osDiskId});done;echo \"List resource Ids to be deleted: \";echo ${deleteingIDs} | tr \" \" \"\\n\";echo -n \"Are you sure to delete these resources (y/n)?\";read answer;if [[ \"$answer\" != \"${answer#[Yy]}\" && -n \"${deleteingIDs}\" ]]; then echo \"Deleting managed resources...Please do not stop.\";az resource delete --verbose --ids ${deleteingIDs};fi',';','echo \"Check if application gateway has deployed...\"; appGateway=$(az resource list -g ${resourceGroup} -n myAppGateway --resource-type Microsoft.Network/applicationGateways | grep \"myAppGateway\");if [ -n \"${appGateway}\" ];then for machine in $managedServerMachineNames;do backendAddresses=$(az network application-gateway address-pool list -g ${resourceGroup} --gateway-name myAppGateway --query [0].backendAddresses | grep \"fqdn\"); if [ $? == 0 ]; then beAddArr=$(echo \"$backendAddresses\" | sed \"s/ //g\" | tr \",\" \"\\n\");index=0;len=0;for item in $beAddArr;do ret=$(echo $item | grep \"$machine\");if [ -z \"$ret\" ];then index=$((index+1));len=$((len+1)); else len=$((len+1));break; fi done; if [[ ${index} -lt ${len} ]]; then echo \"Removing $machine from application gateway, please do not stop.\"; az network application-gateway address-pool update -g ${resourceGroup} --gateway-name myAppGateway --name myGatewayBackendPool --remove backendAddresses ${index};fi;fi; done; fi')]" } } } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/deletenode/src/main/scripts/deletenode.sh b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/deletenode/src/main/scripts/deletenode.sh index f27f78975..da97bd151 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/deletenode/src/main/scripts/deletenode.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/deletenode/src/main/scripts/deletenode.sh @@ -19,9 +19,9 @@ function usage() function validateInput() { - if [[ -z "$wlsUserName" || -z "$wlsPassword" ]] + if [[ -z "$wlsUserName" || -z "$wlsShibboleth" ]] then - echo_stderr "wlsUserName or wlsPassword is required. " + echo_stderr "Weblogic username or password is required. " exit 1 fi @@ -69,7 +69,7 @@ function delete_machine_model() { echo "Deleting managed server name model for $managedServerNames" cat <${scriptPath}/delete-server.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') try: edit() startEdit() @@ -109,7 +109,7 @@ function delete_ms_server_model() { echo "Deleting managed server machine name model for $managedVMNames" cat <${scriptPath}/delete-machine.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') try: edit() startEdit() @@ -195,7 +195,7 @@ function createTempFolder() #main script starts here #read arguments from stdin -read wlsUserName wlsPassword managedServerNames managedVMNames wlsForceShutDown wlsAdminHost wlsAdminPort oracleHome +read wlsUserName wlsShibboleth managedServerNames managedVMNames wlsForceShutDown wlsAdminHost wlsAdminPort oracleHome wlsAdminURL=$wlsAdminHost:$wlsAdminPort hostName=`hostname` diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/pom.xml b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/pom.xml index 9902d3ab3..055d38a5e 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-cluster/pom.xml +++ b/weblogic-azure-vm/arm-oraclelinux-wls-cluster/pom.xml @@ -1,7 +1,7 @@ + ## WebLogic Server (with N-Node Dynamic Cluster) on Microsoft Azure - Marketplace Offerings This git repository is used to maintain the Azure Resource Management (ARM) templates and other scripts used for the implementation of WebLogic Server (with N-Node Dynamic Cluster) on Microsoft Azure. For WebLogic Server running in the Azure Virtual Machines documentation, please refer to the [README documentation](https://github.com/oracle/weblogic-azure/weblogic-azure-vm/arm-oraclelinux-wls/README.md). + diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode-coherence/pom.xml b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode-coherence/pom.xml index b81cc5db2..b42449fdd 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode-coherence/pom.xml +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode-coherence/pom.xml @@ -1,36 +1,37 @@ - + 4.0.0 - com.oracle.weblogic.azure - arm-oraclelinux-wls-dynamic-cluster-addnode-coherence - 1.0.0 - - com.microsoft.azure.iaas - azure-javaee-iaas-parent - 1.0.7 - + com.oracle.weblogic.azure + weblogic-azure-vm + 1.0.0 + ../../pom.xml - + + com.oracle.weblogic.azure + arm-oraclelinux-wls-dynamic-cluster-addnode-coherence + ${version.arm-oraclelinux-wls-dynamic-cluster-addnode-coherence} + jar ${project.artifactId} - ${basedir}/../../arm-ttk/arm-ttk - -TestParameter '@{"SampleName"="addnode-coherence/src/main";"RawRepoPath"="${artifactsLocationBase}/arm-oraclelinux-wls-dynamic-cluster/${git.tag}/"}' - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/pid.properties - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/microsoft-pid.properties + -TestParameter '@{"SampleName"="addnode-coherence/src/main";"RawRepoPath"="${artifactsLocationBase}/arm-oraclelinux-wls-dynamic-cluster/"}' + ${project.basedir}/../../.. + false + false - + diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode-coherence/src/main/arm/addnodedeploy.parameters.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode-coherence/src/main/arm/addnodedeploy.parameters.json index 620516ec5..a35fc0391 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode-coherence/src/main/arm/addnodedeploy.parameters.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode-coherence/src/main/arm/addnodedeploy.parameters.json @@ -29,7 +29,7 @@ "usePreviewImage": { "value": "GEN-UNIQUE" }, - "vmSizeSelectForCoherence": { + "vmSize": { "value": "GEN-UNIQUE" }, "wlsDomainName": { diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode-coherence/src/main/arm/mainTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode-coherence/src/main/arm/mainTemplate.json index 45b1f75cc..f24a984a6 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode-coherence/src/main/arm/mainTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode-coherence/src/main/arm/mainTemplate.json @@ -7,7 +7,7 @@ "metadata": { "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." }, - "defaultValue": "${artifactsLocationBase}/arm-oraclelinux-wls-dynamic-cluster/${git.tag}/addnode-coherence/src/main/" + "defaultValue": "${artifactsLocationBase}/arm-oraclelinux-wls-dynamic-cluster/addnode-coherence/src/main/" }, "_artifactsLocationSasToken": { "type": "securestring", @@ -112,13 +112,23 @@ }, "skuUrnVersion": { "type": "string", - "defaultValue": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "defaultValue": "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", "allowedValues": [ - "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest", - "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest", + "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", + "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest", + "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest", + "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest", + "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest", + "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest", "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest", "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest", - "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" + "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest", + "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel76;Oracle:weblogic-122140-jdk8-rhel76:owls-122140-jdk8-rhel76;latest", + "owls-141100-jdk8-rhel76;Oracle:weblogic-141100-jdk8-rhel76:owls-141100-jdk8-rhel76;latest", + "owls-141100-jdk11-rhel76;Oracle:weblogic-141100-jdk11-rhel76:owls-141100-jdk11-rhel76;latest" ], "metadata": { "description": "The Oracle Linux image with Weblogic and Java preinstalled. Semicolon separated string of Sku, URN, and Version" @@ -137,13 +147,34 @@ "description": "Bool value, if it's set to true, will deploy with preview weblogic image." } }, - "vmSizeSelectForCoherence": { + "vmSize": { "defaultValue": "Standard_A3", "type": "string", "metadata": { "description": "Select appropriate VM Size for Coherence" } }, + "virtualNetworkName": { + "type": "string", + "defaultValue": "wls-vnet", + "metadata": { + "description": "Name of the existing or new VNET" + } + }, + "virtualNetworkResourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "Resource group of Virtual network" + } + }, + "subnetName": { + "type": "string", + "defaultValue": "wls-subnet", + "metadata": { + "description": "Name of the existing or new Subnet" + } + }, "wlsDomainName": { "type": "string", "defaultValue": "wlsd", @@ -164,6 +195,20 @@ "description": "Username for your Weblogic domain name" } }, + "enableDNSConfiguration": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "Boolean value indicating, if DNS Zone Configuration is enabled or not" + } + }, + "customDNSNameForAdminServer": { + "type": "string", + "defaultValue": "none", + "metadata": { + "description": "Custom DNS Name for WebLogic Admin Server" + } + }, "customSSLSettings": { "type": "object", "defaultValue": { @@ -200,7 +245,7 @@ }, "const_mountPointPath": "[concat('/mnt/', variables('name_share'))]", "const_publicIPAddressType": "Dynamic", - "const_vmSize": "[parameters('vmSizeSelectForCoherence')]", + "const_vmSize": "[parameters('vmSize')]", "const_wlsDomainPath": "/u01/domains", "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", "name_linuxImageOfferSKU": "[first(split(parameters('skuUrnVersion'), ';'))]", @@ -210,11 +255,15 @@ "name_scriptCoherenceFile": "setupCoherence.sh", "name_scriptELKConfiguration": "elkIntegrationForConfiguredCluster.sh", "name_share": "wlsshare", - "name_subnet": "Subnet", - "name_virtualNetwork": "[concat(parameters('wlsDomainName'),'_VNET')]", + "name_subnet": "[parameters('subnetName')]", + "name_virtualNetwork": "[parameters('virtualNetworkName')]", "name_vmMachine": "[concat(parameters('managedServerPrefix'),'StorageVM')]", "name_wlsServerPrefix": "[concat(parameters('managedServerPrefix'),'Storage')]", - "ref_subnet": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]" + "ref_subnet": "[resourceId(parameters('virtualNetworkResourceGroupName'), 'Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]", + "name_customHostnameGeneratorscriptFile": "generateCustomHostNameVerifier.sh", + "name_customHostnameVerifierJavaFile": "src/main/java/WebLogicCustomHostNameVerifier.java", + "name_customHostnameValuesTemplate": "src/main/java/HostNameValuesTemplate.txt", + "name_customHostnameVerifierTest" : "src/test/java/WebLogicCustomHostNameVerifierTest.java" }, "functions": [ { @@ -237,7 +286,7 @@ ], "resources": [ { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${dynamic.addnode.coherence.start}", "type": "Microsoft.Resources/deployments", "properties": { @@ -251,8 +300,8 @@ } }, { + "apiVersion": "${azure.apiVersionForPublicIPAddresses}", "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_vmMachine'),copyIndex(variables('const_cacheServerIndexOffset')),variables('name_publicIPAddress'))]", "location": "[parameters('location')]", "copy": { @@ -267,14 +316,14 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualNetworks}", "type": "Microsoft.Network/virtualNetworks/subnets", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_virtualNetwork'), '/', variables('name_subnet'))]", "condition": "[and(empty(variables('name_virtualNetwork')), empty(variables('name_subnet')))]" }, { + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_vmMachine'), copyIndex(variables('const_cacheServerIndexOffset')), variables('name_nic'))]", "location": "[parameters('location')]", "copy": { @@ -305,8 +354,8 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_vmMachine'), copyIndex(variables('const_cacheServerIndexOffset')))]", "location": "[parameters('location')]", "copy": { @@ -338,17 +387,7 @@ "managedDisk": { "storageAccountType": "Standard_LRS" } - }, - "dataDisks": [ - { - "lun": 0, - "createOption": "FromImage", - "diskSizeGB": 900, - "managedDisk": { - "storageAccountType": "Standard_LRS" - } - } - ] + } }, "networkProfile": { "networkInterfaces": [ @@ -360,7 +399,7 @@ "diagnosticsProfile": { "bootDiagnostics": { "enabled": true, - "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', parameters('storageAccountName')), '${azure.apiVersion2}').primaryEndpoints.blob]" + "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', parameters('storageAccountName')), '${azure.apiVersionForStorage}').primaryEndpoints.blob]" } } }, @@ -371,9 +410,9 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines/extensions", "name": "[concat(variables('name_vmMachine'), copyIndex(variables('const_cacheServerIndexOffset')),'/newuserscript')]", - "apiVersion": "${azure.apiVersion}", "location": "[parameters('location')]", "copy": { "name": "virtualMachineExtensionLoop", @@ -390,16 +429,20 @@ "settings": { "fileUris": [ "[uri(parameters('_artifactsLocation'), concat('../../../arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/', variables('name_scriptCoherenceFile'), parameters('_artifactsLocationSasToken')))]", - "[uri(parameters('_artifactsLocation'), concat('../../../arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/', variables('name_scriptELKConfiguration'), parameters('_artifactsLocationSasToken')))]" + "[uri(parameters('_artifactsLocation'), concat('../../../arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/', variables('name_scriptELKConfiguration'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameGeneratorscriptFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierJavaFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameValuesTemplate'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierTest'), parameters('_artifactsLocationSasToken')))]" ] }, "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptCoherenceFile'), ' <<< \"', parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('adminVMName'),' ',variables('const_wlsHome'),' ',variables('const_wlsDomainPath'),' ', parameters('storageAccountName'), ' ', listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2019-04-01').keys[0].value,' ', variables('const_mountPointPath'),' ', parameters('enableCoherenceWebLocalStorage'),' ',parameters('elkSettings').enable, ' ',parameters('elkSettings').elasticsearchEndpoint,' ', parameters('elkSettings').elasticsearchUserName,' ', parameters('elkSettings').elasticsearchPassword, ' ', array.join(parameters('elkSettings').logsToIntegrate), ' ',parameters('elkSettings').logIndex, ' ',variables('name_wlsServerPrefix'),' ',copyIndex(variables('const_cacheServerIndexOffset')),' ',parameters('customSSLSettings').enable,' ',if(parameters('customSSLSettings').enable,base64(parameters('customSSLSettings').customIdentityKeyStoreBase64String), 'null'),' ',if(parameters('customSSLSettings').enable,base64(parameters('customSSLSettings').customIdentityKeyStorePassPhrase), 'null'),' ',if(parameters('customSSLSettings').enable,base64(parameters('customSSLSettings').customIdentityKeyStoreType), 'null'),' ',if(parameters('customSSLSettings').enable,base64(parameters('customSSLSettings').customTrustKeyStoreBase64String), 'null'),' ',if(parameters('customSSLSettings').enable,base64(parameters('customSSLSettings').customTrustKeyStorePassPhrase), 'null'),' ',if(parameters('customSSLSettings').enable,base64(parameters('customSSLSettings').customTrustKeyStoreType), 'null'),' ',if(parameters('customSSLSettings').enable,base64(parameters('customSSLSettings').privateKeyAlias), 'null'),' ',if(parameters('customSSLSettings').enable,base64(parameters('customSSLSettings').privateKeyPassPhrase), 'null'),'\"')]" + "commandToExecute": "[concat('sh',' ',variables('name_scriptCoherenceFile'), ' <<< \"', parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('adminVMName'),' ',variables('const_wlsHome'),' ',variables('const_wlsDomainPath'),' ', parameters('storageAccountName'), ' ', listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '${azure.apiVersionForStorage}').keys[0].value,' ', variables('const_mountPointPath'),' ', parameters('enableCoherenceWebLocalStorage'),' ',parameters('elkSettings').enable, ' ',parameters('elkSettings').elasticsearchEndpoint,' ', parameters('elkSettings').elasticsearchUserName,' ', parameters('elkSettings').elasticsearchPassword, ' ', array.join(parameters('elkSettings').logsToIntegrate), ' ',parameters('elkSettings').logIndex, ' ',variables('name_wlsServerPrefix'),' ',copyIndex(variables('const_cacheServerIndexOffset')),' ',if(parameters('enableDNSConfiguration'),parameters('customDNSNameForAdminServer'),parameters('adminVMName')),' ',parameters('dnsLabelPrefix'),' ',parameters('location'),' ',parameters('customSSLSettings').enable,' ',if(parameters('customSSLSettings').enable,base64(parameters('customSSLSettings').customIdentityKeyStoreBase64String), 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customIdentityKeyStorePassPhrase, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customIdentityKeyStoreType, 'null'),' ',if(parameters('customSSLSettings').enable,base64(parameters('customSSLSettings').customTrustKeyStoreBase64String), 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customTrustKeyStorePassPhrase, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customTrustKeyStoreType, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').privateKeyAlias, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').privateKeyPassPhrase, 'null'),'\"')]" } } }, { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${dynamic.addnode.coherence.end}", "type": "Microsoft.Resources/deployments", "dependsOn": [ diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode/pom.xml b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode/pom.xml index e0081079a..a91a5e9d7 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode/pom.xml +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode/pom.xml @@ -1,36 +1,37 @@ - + 4.0.0 - com.oracle.weblogic.azure - arm-oraclelinux-wls-dynamic-cluster-addnode - 1.0.3 - - com.microsoft.azure.iaas - azure-javaee-iaas-parent - 1.0.7 - + com.oracle.weblogic.azure + weblogic-azure-vm + 1.0.0 + ../../pom.xml - + + com.oracle.weblogic.azure + arm-oraclelinux-wls-dynamic-cluster-addnode + ${version.arm-oraclelinux-wls-dynamic-cluster-addnode} + jar ${project.artifactId} - ${basedir}/../../arm-ttk/arm-ttk - -TestParameter '@{"SampleName"="addnode/src/main";"RawRepoPath"="${artifactsLocationBase}/arm-oraclelinux-wls-dynamic-cluster/${git.tag}/"}' - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/pid.properties - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/microsoft-pid.properties + -TestParameter '@{"SampleName"="addnode/src/main";"RawRepoPath"="${artifactsLocationBase}/arm-oraclelinux-wls-dynamic-cluster/"}' + ${project.basedir}/../../.. + false + false - + diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode/src/main/arm/addNodeToDynamicClusterdeploy.parameters.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode/src/main/arm/addNodeToDynamicClusterdeploy.parameters.json index 7da70bd87..79ce55a28 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode/src/main/arm/addNodeToDynamicClusterdeploy.parameters.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode/src/main/arm/addNodeToDynamicClusterdeploy.parameters.json @@ -46,7 +46,7 @@ "usePreviewImage": { "value": "GEN-UNIQUE" }, - "vmSizeSelect": { + "vmSize": { "value": "GEN-UNIQUE" }, "wlsDomainName": { diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode/src/main/arm/mainTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode/src/main/arm/mainTemplate.json index a3ecd6314..94a0f995b 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode/src/main/arm/mainTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode/src/main/arm/mainTemplate.json @@ -7,7 +7,7 @@ "metadata": { "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." }, - "defaultValue": "${artifactsLocationBase}/arm-oraclelinux-wls-dynamic-cluster/${git.tag}/addnode/src/main/" + "defaultValue": "${artifactsLocationBase}/arm-oraclelinux-wls-dynamic-cluster/addnode/src/main/" }, "_artifactsLocationSasToken": { "type": "securestring", @@ -40,6 +40,13 @@ "description": "Provide admin URL with vm0_public_ip:7001" } }, + "adminVMName": { + "type": "string", + "defaultValue": "adminVM", + "metadata": { + "description": "Provide admin VM Name ex: adminVM" + } + }, "adminUsername": { "type": "string", "defaultValue": "weblogic", @@ -130,13 +137,23 @@ }, "skuUrnVersion": { "type": "string", - "defaultValue": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "defaultValue": "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", "allowedValues": [ - "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest", - "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest", + "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", + "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest", + "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest", + "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest", + "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest", + "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest", "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest", "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest", - "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" + "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest", + "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel76;Oracle:weblogic-122140-jdk8-rhel76:owls-122140-jdk8-rhel76;latest", + "owls-141100-jdk8-rhel76;Oracle:weblogic-141100-jdk8-rhel76:owls-141100-jdk8-rhel76;latest", + "owls-141100-jdk11-rhel76;Oracle:weblogic-141100-jdk11-rhel76:owls-141100-jdk11-rhel76;latest" ], "metadata": { "description": "The Oracle Linux image with Weblogic and Java preinstalled. Semicolon separated string of Sku, URN, and Version" @@ -155,13 +172,34 @@ "description": "Bool value, if it's set to true, will deploy with preview weblogic image." } }, - "vmSizeSelect": { + "vmSize": { "type": "string", "defaultValue": "Standard_A3", "metadata": { "description": "Select appropriate VM Size as per requirement" } }, + "virtualNetworkName": { + "type": "string", + "defaultValue": "wls-vnet", + "metadata": { + "description": "Name of the existing or new VNET" + } + }, + "virtualNetworkResourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "Resource group of Virtual network" + } + }, + "subnetName": { + "type": "string", + "defaultValue": "wls-subnet", + "metadata": { + "description": "Name of the existing or new Subnet" + } + }, "wlsDomainName": { "type": "string", "defaultValue": "wlsd", @@ -181,6 +219,20 @@ "description": "Password for your Weblogic domain name" } }, + "enableDNSConfiguration": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "Boolean value indicating, if DNS Zone Configuration is enabled or not" + } + }, + "customDNSNameForAdminServer": { + "type": "string", + "defaultValue": "none", + "metadata": { + "description": "Custom DNS Name for WebLogic Admin Server" + } + }, "customSSLSettings": { "type": "object", "defaultValue": { @@ -218,7 +270,7 @@ "const_managedVMPrefix": "[concat(parameters('managedServerPrefix'),'VM')]", "const_mountPointPath": "[concat('/mnt/', variables('name_share'))]", "const_publicIPAddressType": "Dynamic", - "const_vmSize": "[parameters('vmSizeSelect')]", + "const_vmSize": "[parameters('vmSize')]", "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", "const_wlsDomainPath": "/u01/domains", "name_linuxImageOfferSKU": "[first(split(parameters('skuUrnVersion'), ';'))]", @@ -228,10 +280,14 @@ "name_scriptELKConfiguration": "elkIntegrationForDynamicCluster.sh", "name_scriptFile": "addNodeToDynamicCluster.sh", "name_share": "wlsshare", - "name_subnet": "Subnet", - "name_virtualNetwork": "[concat(parameters('wlsDomainName'),'_VNET')]", + "name_subnet": "[parameters('subnetName')]", + "name_virtualNetwork": "[parameters('virtualNetworkName')]", "name_vmMachine": "[concat(parameters('managedServerPrefix'),'VM')]", - "ref_subnet": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]" + "ref_subnet": "[resourceId(parameters('virtualNetworkResourceGroupName'), 'Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]", + "name_customHostnameGeneratorscriptFile": "generateCustomHostNameVerifier.sh", + "name_customHostnameVerifierJavaFile": "src/main/java/WebLogicCustomHostNameVerifier.java", + "name_customHostnameValuesTemplate": "src/main/java/HostNameValuesTemplate.txt", + "name_customHostnameVerifierTest" : "src/test/java/WebLogicCustomHostNameVerifierTest.java" }, "functions": [ { @@ -255,7 +311,7 @@ "resources": [ { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${dynamic.addnode.start}", "properties": { "mode": "Incremental", @@ -267,8 +323,8 @@ } }, { + "apiVersion": "${azure.apiVersionForPublicIPAddresses}", "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_vmMachine'),copyIndex(variables('const_appNodeMachineOffset')),variables('name_publicIPAddress'))]", "location": "[parameters('location')]", "copy": { @@ -283,14 +339,14 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualNetworks}", "type": "Microsoft.Network/virtualNetworks/subnets", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_virtualNetwork'), '/', variables('name_subnet'))]", "condition": "[and(empty(variables('name_virtualNetwork')), empty(variables('name_subnet')))]" }, { + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_vmMachine'),copyIndex(variables('const_appNodeMachineOffset')), variables('name_nic'))]", "location": "[parameters('location')]", "copy": { @@ -321,8 +377,8 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_vmMachine'), copyIndex(variables('const_appNodeMachineOffset')))]", "location": "[parameters('location')]", "copy": { @@ -354,17 +410,7 @@ "managedDisk": { "storageAccountType": "Standard_LRS" } - }, - "dataDisks": [ - { - "lun": 0, - "createOption": "FromImage", - "diskSizeGB": 900, - "managedDisk": { - "storageAccountType": "Standard_LRS" - } - } - ] + } }, "networkProfile": { "networkInterfaces": [ @@ -376,7 +422,7 @@ "diagnosticsProfile": { "bootDiagnostics": { "enabled": true, - "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', parameters('storageAccountName')), '${azure.apiVersion2}').primaryEndpoints.blob]" + "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', parameters('storageAccountName')), '${azure.apiVersionForStorage}').primaryEndpoints.blob]" } } }, @@ -387,8 +433,8 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_vmMachine'), copyIndex(variables('const_appNodeMachineOffset')), '/newuserscript')]", "location": "[parameters('location')]", "copy": { @@ -406,17 +452,21 @@ "settings": { "fileUris": [ "[uri(parameters('_artifactsLocation'), concat('scripts/', variables('name_scriptFile'), parameters('_artifactsLocationSasToken')))]", - "[uri(parameters('_artifactsLocation'), concat('../../../arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/', variables('name_scriptELKConfiguration'), parameters('_artifactsLocationSasToken')))]" + "[uri(parameters('_artifactsLocation'), concat('../../../arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/', variables('name_scriptELKConfiguration'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameGeneratorscriptFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierJavaFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameValuesTemplate'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierTest'), parameters('_artifactsLocationSasToken')))]" ] }, "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'),' <<< \"',parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('managedServerPrefix'),' ',copyIndex(variables('const_appNodeMachineOffset')),' ', parameters('adminURL'),' ',variables('const_wlsHome'),' ',variables('const_wlsDomainPath'),' ', parameters('dynamicClusterSize'),' ', variables('const_managedVMPrefix'),' ',parameters('storageAccountName'), ' ', listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2019-04-01').keys[0].value,' ', variables('const_mountPointPath'),' ', if(parameters('aadsSettings').enable, parameters('aadsSettings').certificateBase64String, 'null'),' ',if(parameters('aadsSettings').enable, parameters('aadsSettings').publicIP, 'null'),' ', if(parameters('aadsSettings').enable, parameters('aadsSettings').serverHost, 'null'),' ',parameters('elkSettings').enable,' ', parameters('elkSettings').elasticsearchEndpoint,' ', parameters('elkSettings').elasticsearchUserName,' ', parameters('elkSettings').elasticsearchPassword,' ', array.join(parameters('elkSettings').logsToIntegrate), ' ', parameters('elkSettings').logIndex, ' ', parameters('maxDynamicClusterSize'),' ',parameters('customSSLSettings').enable,' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customIdentityKeyStoreBase64String, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customIdentityKeyStorePassPhrase, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customIdentityKeyStoreType, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customTrustKeyStoreBase64String, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customTrustKeyStorePassPhrase, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customTrustKeyStoreType, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').privateKeyAlias, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').privateKeyPassPhrase, 'null'),'\"')]" + "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'),' <<< \"',parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('managedServerPrefix'),' ',copyIndex(variables('const_appNodeMachineOffset')),' ', parameters('adminURL'),' ',parameters('adminVMName'),' ',variables('const_wlsHome'),' ',variables('const_wlsDomainPath'),' ', parameters('dynamicClusterSize'),' ', variables('const_managedVMPrefix'),' ',parameters('storageAccountName'), ' ', listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '${azure.apiVersionForStorage}').keys[0].value,' ', variables('const_mountPointPath'),' ', if(parameters('aadsSettings').enable, parameters('aadsSettings').certificateBase64String, 'null'),' ',if(parameters('aadsSettings').enable, parameters('aadsSettings').publicIP, 'null'),' ', if(parameters('aadsSettings').enable, parameters('aadsSettings').serverHost, 'null'),' ',parameters('elkSettings').enable,' ', parameters('elkSettings').elasticsearchEndpoint,' ', parameters('elkSettings').elasticsearchUserName,' ', parameters('elkSettings').elasticsearchPassword,' ', array.join(parameters('elkSettings').logsToIntegrate), ' ', parameters('elkSettings').logIndex, ' ', parameters('maxDynamicClusterSize'),' ',if(parameters('enableDNSConfiguration'),parameters('customDNSNameForAdminServer'),parameters('adminVMName')),' ',parameters('dnsLabelPrefix'),' ',parameters('location'),' ',parameters('customSSLSettings').enable,' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customIdentityKeyStoreBase64String, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customIdentityKeyStorePassPhrase, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customIdentityKeyStoreType, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customTrustKeyStoreBase64String, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customTrustKeyStorePassPhrase, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').customTrustKeyStoreType, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').privateKeyAlias, 'null'),' ',if(parameters('customSSLSettings').enable,parameters('customSSLSettings').privateKeyPassPhrase, 'null'),'\"')]" } } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${dynamic.addnode.end}", "dependsOn": [ "virtualMachineExtensionLoop" diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode/src/main/scripts/addNodeToDynamicCluster.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode/src/main/scripts/addNodeToDynamicCluster.sh index 28abb0934..3dbb23897 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode/src/main/scripts/addNodeToDynamicCluster.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/addnode/src/main/scripts/addNodeToDynamicCluster.sh @@ -151,9 +151,8 @@ function cleanup() rm -rf $wlsDomainPath/managed-domain.yaml rm -rf $wlsDomainPath/weblogic-deploy.zip rm -rf $wlsDomainPath/weblogic-deploy - rm -rf $wlsDomainPath/deploy-app.yaml - rm -rf $wlsDomainPath/shoppingcart.zip rm -rf $wlsDomainPath/*.py + rm -rf ${CUSTOM_HOSTNAME_VERIFIER_HOME} echo "Cleanup completed." } @@ -189,6 +188,8 @@ topology: '${dynamicServerTemplate}' : ListenPort: ${wlsManagedPort} Cluster: '${wlsClusterName}' + ServerStart: + Arguments: '${SERVER_STARTUP_ARGS}' SSL: HostnameVerificationIgnored: true HostnameVerifier: 'None' @@ -398,9 +399,10 @@ Description=WebLogic nodemanager service Type=simple # Note that the following three parameters should be changed to the correct paths # on your own system -WorkingDirectory="$wlsDomainPath/$wlsDomainName" -ExecStart="$wlsDomainPath/$wlsDomainName/bin/startNodeManager.sh" -ExecStop="$wlsDomainPath/$wlsDomainName/bin/stopNodeManager.sh" +WorkingDirectory=/u01/domains +Environment="JAVA_OPTIONS=${SERVER_STARTUP_ARGS}" +ExecStart=/bin/bash $wlsDomainPath/$wlsDomainName/bin/startNodeManager.sh +ExecStop=/bin/bash $wlsDomainPath/$wlsDomainName/bin/stopNodeManager.sh User=oracle Group=oracle KillMode=process @@ -463,8 +465,8 @@ function mountFileShare() fi echo "chmod 600 /etc/smbcredentials/${storageAccountName}.cred" sudo chmod 600 /etc/smbcredentials/${storageAccountName}.cred - echo "//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred ,dir_mode=0777,file_mode=0777,serverino" - sudo bash -c "echo \"//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred ,dir_mode=0777,file_mode=0777,serverino\" >> /etc/fstab" + echo "//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino" + sudo bash -c "echo \"//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino\" >> /etc/fstab" echo "mount -t cifs //${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino" sudo mount -t cifs //${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino if [[ $? != 0 ]]; @@ -520,7 +522,7 @@ function importAADCertificate() { # import the key to java security . $oracleHome/oracle_common/common/bin/setWlstEnv.sh - # For AAD failure: exception happens when importing certificate to JDK 11.0.7 + # For Entra ID failure: exception happens when importing certificate to JDK 11.0.7 # ISSUE: https://github.com/wls-eng/arm-oraclelinux-wls/issues/109 # JRE was removed since JDK 11. java_version=$(java -version 2>&1 | sed -n ';s/.* version "\(.*\)\.\(.*\)\..*"/\1\2/p;') @@ -556,14 +558,14 @@ function importAADCertificateIntoWLSCustomTrustKeyStore() exit 1 fi - # For SSL enabled causes AAD failure #225 + # For SSL enabled causes Entra ID failure #225 # ISSUE: https://github.com/wls-eng/arm-oraclelinux-wls/issues/225 - echo "Importing AAD Certificate into WLS Custom Trust Key Store: " + echo "Importing Entra ID Certificate into WLS Custom Trust Key Store: " sudo ${JAVA_HOME}/bin/keytool -noprompt -import -trustcacerts -keystore {KEYSTORE_PATH}/trust.keystore -storepass ${customTrustKeyStorePassPhrase} -alias aadtrust -file ${addsCertificate} -storetype ${customTrustKeyStoreType} else - echo "customSSL not enabled. Not required to configure AAD for WebLogic Custom SSL" + echo "customSSL not enabled. Not required to configure Entra ID for WebLogic Custom SSL" fi } @@ -600,6 +602,7 @@ function parseAndSaveCustomSSLKeyStoreData() echo "$customIdentityKeyStoreBase64String" > ${KEYSTORE_PATH}/identityKeyStoreCerBase64String.txt cat ${KEYSTORE_PATH}/identityKeyStoreCerBase64String.txt | base64 -d > ${KEYSTORE_PATH}/identity.keystore customSSLIdentityKeyStoreFile=${KEYSTORE_PATH}/identity.keystore + customIdentityKeyStorePassPhrase="$(echo $customIdentityKeyStorePassPhrase | base64 --decode)" rm -rf ${KEYSTORE_PATH}/identityKeyStoreCerBase64String.txt @@ -609,20 +612,46 @@ function parseAndSaveCustomSSLKeyStoreData() echo "$customTrustKeyStoreBase64String" > ${KEYSTORE_PATH}/trustKeyStoreCerBase64String.txt cat ${KEYSTORE_PATH}/trustKeyStoreCerBase64String.txt | base64 -d > ${KEYSTORE_PATH}/trust.keystore customSSLTrustKeyStoreFile=${KEYSTORE_PATH}/trust.keystore + customTrustKeyStorePassPhrase="$(echo $customTrustKeyStorePassPhrase | base64 --decode)" rm -rf ${KEYSTORE_PATH}/trustKeyStoreCerBase64String.txt + + privateKeyAlias="$(echo $privateKeyAlias | base64 --decode)" + privateKeyPassPhrase="$(echo $privateKeyPassPhrase | base64 --decode)" +} + +function generateCustomHostNameVerifier() +{ + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME} + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/test/java + cp ${BASE_DIR}/generateCustomHostNameVerifier.sh ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh + cp ${BASE_DIR}/WebLogicCustomHostNameVerifier.java ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java/WebLogicCustomHostNameVerifier.java + cp ${BASE_DIR}/HostNameValuesTemplate.txt ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java/HostNameValuesTemplate.txt + cp ${BASE_DIR}/WebLogicCustomHostNameVerifierTest.java ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/test/java/WebLogicCustomHostNameVerifierTest.java + chown -R $username:$groupname ${CUSTOM_HOSTNAME_VERIFIER_HOME} + chmod +x ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh + + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh ${adminVMName} ${customDNSNameForAdminServer} ${customDNSNameForAdminServer} ${dnsLabelPrefix} ${wlsDomainName} ${location}" +} + +function copyCustomHostNameVerifierJarsToWebLogicClasspath() +{ + runuser -l oracle -c "cp ${CUSTOM_HOSTNAME_VERIFIER_HOME}/output/*.jar $oracleHome/wlserver/server/lib/;" + + echo "Modify WLS CLASSPATH to include hostname verifier jars...." + sed -i 's;^WEBLOGIC_CLASSPATH="${WL_HOME}/server/lib/postgresql.*;&\nWEBLOGIC_CLASSPATH="${WL_HOME}/server/lib/hostnamevalues.jar:${WL_HOME}/server/lib/weblogicustomhostnameverifier.jar:${WEBLOGIC_CLASSPATH}";' $oracleHome/oracle_common/common/bin/commExtEnv.sh + echo "Modified WLS CLASSPATH to include hostname verifier jars." } + #main script starts here SCRIPT_PWD=`pwd` +CURR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +BASE_DIR="$(readlink -f ${CURR_DIR})" -# store arguments in a special array -#args=("$@") -# get number of elements -#ELEMENTS=${#args[@]} - -read wlsDomainName wlsUserName wlsPassword managedServerPrefix serverIndex wlsAdminURL oracleHome wlsDomainPath dynamicClusterSize vmNamePrefix storageAccountName storageAccountKey mountpointPath wlsADSSLCer wlsLDAPPublicIP adServerHost enableELK elasticURI elasticUserName elasticPassword logsToIntegrate logIndex maxDynamicClusterSize isCustomSSLEnabled customIdentityKeyStoreBase64String customIdentityKeyStorePassPhrase customIdentityKeyStoreType customTrustKeyStoreBase64String customTrustKeyStorePassPhrase customTrustKeyStoreType privateKeyAlias privateKeyPassPhrase +read wlsDomainName wlsUserName wlsPassword managedServerPrefix serverIndex wlsAdminURL adminVMName oracleHome wlsDomainPath dynamicClusterSize vmNamePrefix storageAccountName storageAccountKey mountpointPath wlsADSSLCer wlsLDAPPublicIP adServerHost enableELK elasticURI elasticUserName elasticPassword logsToIntegrate logIndex maxDynamicClusterSize customDNSNameForAdminServer dnsLabelPrefix location isCustomSSLEnabled customIdentityKeyStoreBase64String customIdentityKeyStorePassPhrase customIdentityKeyStoreType customTrustKeyStoreBase64String customTrustKeyStorePassPhrase customTrustKeyStoreType privateKeyAlias privateKeyPassPhrase isCustomSSLEnabled="${isCustomSSLEnabled,,}" @@ -643,6 +672,8 @@ WEBLOGIC_DEPLOY_TOOL=https://github.com/oracle/weblogic-deploy-tooling/releases/ username="oracle" groupname="oracle" KEYSTORE_PATH="$wlsDomainPath/$wlsDomainName/keystores" +SERVER_STARTUP_ARGS="-Dlog4j2.formatMsgNoLookups=true" +CUSTOM_HOSTNAME_VERIFIER_HOME="/u01/app/custom-hostname-verifier" cleanup installUtilities @@ -662,8 +693,11 @@ if [ "$enableAAD" == "true" ];then fi create_managedSetup +generateCustomHostNameVerifier +copyCustomHostNameVerifierJarsToWebLogicClasspath create_nodemanager_service enabledAndStartNodeManagerService +configureCustomHostNameVerifier start_cluster echo "enable ELK? ${enableELK}" diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/pom.xml b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/pom.xml index 914e7aae1..0d8940bc9 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/pom.xml +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/pom.xml @@ -1,35 +1,34 @@ - + 4.0.0 - com.oracle.weblogic.azure - arm-oraclelinux-wls-dynamic-cluster - 1.0.24 - - com.microsoft.azure.iaas - azure-javaee-iaas-parent - 1.0.7 - + com.oracle.weblogic.azure + weblogic-azure-vm + 1.0.0 + ../../pom.xml - + + com.oracle.weblogic.azure + arm-oraclelinux-wls-dynamic-cluster + ${version.arm-oraclelinux-wls-dynamic-cluster} jar ${project.artifactId} - ${basedir}/../../arm-ttk/arm-ttk - -TestParameter '@{"PasswordMinLength"=5}' - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/pid.properties - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/microsoft-pid.properties + ${project.basedir}/../../.. + false + false - + - + diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/createUiDefinition.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/createUiDefinition.json index bc469557b..27137136f 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/createUiDefinition.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/createUiDefinition.json @@ -1,1952 +1,1503 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", - "handler": "Microsoft.Azure.CreateUIDef", - "version": "0.1.2-preview", - "parameters": { - "basics": [ - { - "name": "skuUrnVersion", - "type": "Microsoft.Common.DropDown", - "label": "Oracle WebLogic Image", - "defaultValue": "WebLogic Server 14.1.1.0.0 and JDK11 on Oracle Linux 7.6", - "toolTip": "Choose Oracle WebLogic image, which is provided by Oracle, with Java and WebLogic preinstalled.", - "constraints": { - "allowedValues": [ - { - "label": "WebLogic Server 12.2.1.3.0 and JDK8 on Oracle Linux 7.4", - "value": "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest" - }, - { - "label": "WebLogic Server 12.2.1.3.0 and JDK8 on Oracle Linux 7.3", - "value": "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest" - }, - { - "label": "WebLogic Server 12.2.1.4.0 and JDK8 on Oracle Linux 7.6", - "value": "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest" - }, - { - "label": "WebLogic Server 14.1.1.0.0 and JDK8 on Oracle Linux 7.6", - "value": "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest" - }, - { - "label": "WebLogic Server 14.1.1.0.0 and JDK11 on Oracle Linux 7.6", - "value": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" - } - ], - "required": true - }, - "visible": true - }, - { - "name": "vmSizeSelect", - "type": "Microsoft.Compute.SizeSelector", - "label": "Virtual machine size", - "toolTip": "The size of virtual machine to provision.", - "recommendedSizes": [ - "Standard_A1", - "Standard_A2", - "Standard_A3", - "Standard_A4", - "Standard_B1ms" - ], - "constraints": { - "excludedSizes": [ - "Standard_B1ls", - "Standard_A0", - "Basic_A0", - "Standard_B1s" - ] - }, - "osPlatform": "Linux", - "count": "1", - "visible": true - }, - { - "name": "basicsRequired", - "type": "Microsoft.Common.Section", - "label": "Credentials for Virtual Machines and WebLogic", - "elements": [ - { - "name": "adminUsername", - "type": "Microsoft.Common.TextBox", - "label": "Username for admin account of VMs", - "defaultValue": "weblogic", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - }, - "visible": true - }, - { - "name": "adminPasswordOrKey", - "type": "Microsoft.Compute.CredentialsCombo", - "label": { - "authenticationType": "Authentication type", - "password": "Password", - "confirmPassword": "Confirm password", - "sshPublicKey": "SSH public key" - }, - "toolTip": { - "authenticationType": "Use username and password or SSH public key for authentication to the VM", - "password": "Password for admin account of VMs", - "sshPublicKey": "SSH key for admin account of VMs" - }, - "constraints": { - "required": true, - "customPasswordRegex": "^((?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])|(?=.*[0-9])(?=.*[a-z])(?=.*[!@#$%^&*])|(?=.*[0-9])(?=.*[A-Z])(?=.*[!@#$%^&*])|(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*])).{12,72}$", - "customValidationMessage": "Password must be at least 12 characters long and have 3 out of the following: one number, one lower case, one upper case, or one special character" - }, - "options": { - "hideConfirmation": false, - "hidePassword": false - }, - "osPlatform": "Linux", - "visible": true - }, - { - "name": "wlsUserName", - "type": "Microsoft.Common.TextBox", - "label": "Username for WebLogic Administrator", - "defaultValue": "weblogic", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - }, - "visible": true - }, - { - "name": "wlsPassword", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Password for WebLogic Administrator", - "confirmPassword": "Confirm password" - }, - "toolTip": "Password for WebLogic Administrator", - "constraints": { - "required": true, - "regex": "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)[A-Za-z\\d]{12,}$", - "validationMessage": "The password must contain at least 12 characters, with at least 1 uppercase letter, 1 lowercase letter and 1 number, and special characters are not allowed." - }, - "options": { - "hideConfirmation": false - }, - "visible": true - }, - { - "name": "dynamicClusterSize", - "type": "Microsoft.Common.TextBox", - "label": "Initial Dynamic Cluster Size", - "defaultValue": "3", - "toolTip": "Initial Number of Managed Servers that will be configured in the Dynamic Cluster", - "constraints": { - "required": true, - "regex": "^(2|3|4|5|6|7|8|9|10){1,2}$", - "validationMessage": "Initial Number of Managed Servers that will be configured in the Dynamic Cluster" - }, - "visible": true - }, - { - "name": "maxDynamicClusterSize", - "type": "Microsoft.Common.TextBox", - "label": "Maximum Dynamic Cluster Size", - "defaultValue": "8", - "toolTip": "Maximum Number of Managed Servers allowed to be configured in the Dynamic Cluster", - "constraints": { - "required": true, - "regex": "^(2|3|4|5|6|7|8|9|10){1,2}$", - "validationMessage": "Maximum Number of Managed Servers allowed to be configured in the Dynamic Cluster" - }, - "visible": true - } - ], - "visible": true - }, - { - "name": "basicsOptional", - "type": "Microsoft.Common.Section", - "label": "Optional Basic Configuration", - "elements": [ - { - "name": "basicsOptionalAcceptDefaults", - "type": "Microsoft.Common.OptionsGroup", - "label": "Accept defaults for optional configuration?", - "defaultValue": "Yes", - "toolTip": "Select 'No' to edit optional basic configuration.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": "false" - }, - { - "label": "No", - "value": "true" - } - ], - "required": true - } - }, - { - "name": "dnsLabelPrefix", - "type": "Microsoft.Common.TextBox", - "label": "DNS Label Prefix", - "toolTip": "The string to prepend to the DNS label.", - "defaultValue": "wls", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{3,10}$", - "validationMessage": "The prefix must be between 3 and 10 characters long and contain letters, numbers only." - }, - "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" - }, - { - "name": "managedServerPrefix", - "type": "Microsoft.Common.TextBox", - "label": "Managed Server Prefix", - "toolTip": "The string to prepend to the name of the managed server. Must start with letters and not have a run of more than eight digits.", - "defaultValue": "msp", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{3,20}$", - "validationMessage": "The prefix must be between 3 and 20 characters long and contain letters, numbers only." - }, - "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" - }, - { - "name": "wlsDomainName", - "type": "Microsoft.Common.TextBox", - "label": "WebLogic Domain Name", - "toolTip": "The name of the WebLogic Domain to create.", - "defaultValue": "clusterDomain", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{3,20}$", - "validationMessage": "The Domain Name must be between 3 and 20 characters long and contain letters, numbers only." - }, - "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" - }, - { - "name": "portsToExpose", - "label": "Ports and port ranges to expose (N or N-N, comma separated)", - "type": "Microsoft.Common.TextBox", - "toolTip": "Ports and port ranges to expose (N or N-N, comma separated)", - "defaultValue": "80,443,7001-9000", - "constraints": { - "required": true, - "regex": "^(((([0-9]+-[0-9]+)|([0-9]+))[,]?)+[^,]){1,1000}$", - "validationMessage": "Only numbers, hyphen separated ranges of numbers, separated by commas" - }, - "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" - }, - { - "name": "denyPublicTrafficForAdminServer", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deny public traffic for admin server?", - "defaultValue": "No", - "toolTip": "Select 'Yes' to deny public traffic for admin server. Configuration here for port 7001 and 7002 has a higher priority than above.", - "constraints": { - "allowedValues": [ - { - "label": "No", - "value": false - }, - { - "label": "Yes", - "value": true - } - ], - "required": true - }, - "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" - }, - { - "name": "enableAdminHTTPListenPort", - "type": "Microsoft.Common.OptionsGroup", - "label": "Enable HTTP listen port on WebLogic Administration Server?", - "defaultValue": "Yes", - "toolTip": "Select 'No' to disable HTTP listen port on WebLogic Administration Server.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": true - }, - { - "label": "No", - "value": false - } - ], - "required": true - }, - "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" - }, - { - "name": "useSystemAssignedManagedIdentity", - "label": "Cause a system assigned managed identity to be created for the VM(s).", - "type": "Microsoft.Common.OptionsGroup", - "toolTip": "System assigned managed identities enable credential-free secure access to many Azure resources from this VM.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": true - }, - { - "label": "No", - "value": false - } - ], - "required": true - }, - "defaultValue": "Yes", - "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" - } - ], - "visible": true - }, - { - "name": "About", - "type": "Microsoft.Common.InfoBox", - "options": { - "icon": "None", - "text": "Template version ${project.version}" - }, - "visible": "[bool('${template.version.visible}')]" - }, - { - "name": "howToReportIssues", - "type": "Microsoft.Common.Section", - "label": "Report issues, get help, and share feedback", - "elements": [ - { - "name": "howToReportIssueText", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "If you encounter problems during the deployment of Oracle WebLogic Server, report them here.", - "link": { - "label": "Issue tracker", - "uri": "https://aka.ms/arm-oraclelinux-wls-issues" - } - } - }, - { - "name": "howToJoinSlack", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "If you want to interact directly with the Oracle WebLogic community, join the public Slack channel named 'oracle-weblogic'.", - "link": { - "label": "Join Slack", - "uri": "https://aka.ms/arm-oraclelinux-wls-slack" - } - } - }, - { - "name": "survey", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "To get free help with Azure migration from the development team, fill out this survey.", - "link": { - "label": "Take survey", - "uri": "https://aka.ms/wls-on-azure-survey" - } - } - } - ], - "visible": true - } - ], - "steps": [ - { - "name": "section_sslConfiguration", - "type": "Microsoft.Common.Section", - "label": "TLS/SSL Configuration", - "elements": [ - { - "name": "sslConfigurationText", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "Selecting 'Yes' here will cause the template to provision WebLogic Administration Console on HTTPS (Secure) port, with your own TLS/SSL certificate.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-ssl-config" - } - } - }, - { - "name": "enableCustomSSL", - "type": "Microsoft.Common.OptionsGroup", - "label": "Configure WebLogic Administration Console on HTTPS (Secure) port, with your own TLS/SSL certificate?", - "defaultValue": "No", - "toolTip": "Select 'Yes' to configure WebLogic Administration Console on HTTPS (Secure) port with your own TLS/SSL certificate.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": true - }, - { - "label": "No", - "value": false - } - ], - "required": false - } - }, - { - "name": "sslConfigurationAccessOption", - "type": "Microsoft.Common.OptionsGroup", - "visible": "[steps('section_sslConfiguration').enableCustomSSL]", - "label": "How would you like to provide required configuration", - "defaultValue": "Upload existing KeyStores", - "toolTip": "Select 'Upload existing KeyStores' to use local stored KeyStores.", - "constraints": { - "allowedValues": [ - { - "label": "Upload existing KeyStores", - "value": "uploadConfig" - }, - { - "label": "Use KeyStores stored in Azure Key Vault", - "value": "keyVaultStoredConfig" - } - ], - "required": false - } - }, - { - "name": "uploadedCustomSSLSettings", - "type": "Microsoft.Common.Section", - "visible": "[and(steps('section_sslConfiguration').enableCustomSSL, equals(steps('section_sslConfiguration').sslConfigurationAccessOption, 'uploadConfig'))]", - "label": "TLS/SSL Configuration Settings", - "elements": [ - { - "name": "sslKeystoreInfo0", - "type": "Microsoft.Common.InfoBox", - "visible": "true", - "options": { - "icon": "Info", - "text": "You must provide different files for identity and trust KeyStores. Select here for more details.", - "uri": "https://aka.ms/arm-oraclelinux-wls-ssl-configuration" - } - }, - { - "name": "uploadedCustomIdentityKeyStoreData", - "type": "Microsoft.Common.FileUpload", - "label": "Identity KeyStore Data file(.jks,.p12)", - "toolTip": "Identity KeyStore for TLS/SSL configuration", - "constraints": { - "required": true, - "accept": ".jks,.p12" - }, - "options": { - "multiple": false, - "uploadMode": "file", - "openMode": "binary" - }, - "visible": true - }, - { - "name": "uploadedCustomIdentityKeyStorePassphrase", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Password", - "confirmPassword": "Confirm password" - }, - "toolTip": " The passphrase for the Identity KeyStore", - "constraints": { - "required": true, - "regex": "^.{6,}$", - "validationMessage": "Keypass must be at least 6 characters long." - }, - "options": { - "hideConfirmation": false - }, - "visible": true - }, - { - "name": "uploadedCustomIdentityKeyStoreType", - "type": "Microsoft.Common.DropDown", - "visible": "true", - "label": "The Identity KeyStore type (JKS,PKCS12)", - "defaultValue": "JKS", - "toolTip": "One of the supported KeyStore types", - "constraints": { - "allowedValues": [ - { - "label": "JKS", - "value": "JKS" - }, - { - "label": "PKCS12", - "value": "PKCS12" - } - ], - "required": true - } - }, - { - "name": "uploadedPrivateKeyAlias", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The alias of the server's private key within the Identity KeyStore", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "uploadedPrivateKeyPassPhrase", - "type": "Microsoft.Common.PasswordBox", - "visible": "true", - "label": { - "password": "The passphrase for the server's private key within the Identity KeyStore", - "confirmPassword": "Confirm passphrase" - }, - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^.{6,}$", - "validationMessage": "Keypass must be at least 6 characters long." - }, - "options": { - "hideConfirmation": false - } - }, - { - "name": "uploadedCustomTrustKeyStoreData", - "type": "Microsoft.Common.FileUpload", - "label": "Trust KeyStore Data file(.jks,.p12)", - "toolTip": "Trust KeyStore for TLS/SSL configuration.", - "constraints": { - "required": true, - "accept": ".jks,.p12" - }, - "options": { - "multiple": false, - "uploadMode": "file", - "openMode": "binary" - }, - "visible": true - }, - { - "name": "uploadedCustomTrustKeyStorePassPhrase", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Password", - "confirmPassword": "Confirm password" - }, - "toolTip": " The passphrase for the Trust KeyStore", - "constraints": { - "required": true, - "regex": "^.{6,}$", - "validationMessage": "Keypass must be at least 6 characters long." - }, - "options": { - "hideConfirmation": false - }, - "visible": true - }, - { - "name": "uploadedCustomTrustKeyStoreType", - "type": "Microsoft.Common.DropDown", - "visible": "true", - "label": "The Trust KeyStore type (JKS,PKCS12)", - "defaultValue": "JKS", - "toolTip": "One of the supported KeyStore types", - "constraints": { - "allowedValues": [ - { - "label": "JKS", - "value": "JKS" - }, - { - "label": "PKCS12", - "value": "PKCS12" - } - ], - "required": true - } - } - ] - }, - { - "name": "keyVaultStoredCustomSSLSettings", - "type": "Microsoft.Common.Section", - "visible": "[and(steps('section_sslConfiguration').enableCustomSSL, equals(steps('section_sslConfiguration').sslConfigurationAccessOption, 'keyVaultStoredConfig'))]", - "label": "TLS/SSL Configuration Settings", - "elements": [ - { - "name": "sslKeystoreInfo1", - "type": "Microsoft.Common.InfoBox", - "visible": "true", - "options": { - "icon": "Info", - "text": "You must provide different files for identity and trust KeyStores. Select here for more details.", - "uri": "https://aka.ms/arm-oraclelinux-wls-ssl-configuration" - } - }, - { - "name": "keyVaultText", - "type": "Microsoft.Common.TextBlock", - "visible": "true", - "options": { - "text": "Enabling a HTTPS (Secure) port for the Administration Console requires you to obtain a valid TLS/SSL certificate. The template will look for the certificate and other configuration items in the Azure Key Vault specified here.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-cluster-app-gateway-key-vault" - } - } - }, - { - "name": "keyVaultResourceGroup", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "Resource group name in current subscription containing the Key Vault", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1})$", - "validationMessage": "[if(greater(length(steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultResourceGroup), 90),'Resource group names only allow up to 90 characters.', 'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" - } - }, - { - "name": "keyVaultName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "Name of the Azure Key Vault containing secrets for the TLS/SSL certificate", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^(?=.{3,24}$)[a-zA-Z](([a-z0-9A-Z]*|(?:\\-[^\\-][a-z0-9A-Z]*))*)$", - "validationMessage": "[if(or(greater(length(steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultName), 24), less(length(steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultName), 3)),'Vault name must be between 3-24 alphanumeric characters. The name must begin with a letter, end with a letter or digit, and not contain consecutive hyphens.','Vault name must only contain alphanumeric characters and dashes and cannot start with a number')]" - } - }, - { - "name": "keyVaultCustomIdentityKeyStoreDataSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the Identity KeyStore Data", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "keyVaultCustomIdentityKeyStorePassPhraseSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the passphrase for the Identity KeyStore", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "keyVaultCustomIdentityKeyStoreType", - "type": "Microsoft.Common.DropDown", - "visible": "true", - "label": "The Identity KeyStore type (JKS,PKCS12)", - "defaultValue": "JKS", - "toolTip": "One of the supported KeyStore types", - "constraints": { - "allowedValues": [ - { - "label": "JKS", - "value": "JKS" - }, - { - "label": "PKCS12", - "value": "PKCS12" - } - ], - "required": true - } - }, - { - "name": "keyVaultPrivateKeyAliasSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the private key Alias", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "keyVaultPrivateKeyPassPhraseSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the passphrase for the private key", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "keyVaultCustomTrustKeyStoreDataSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the Trust KeyStore Data", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "keyVaultCustomTrustKeyStorePassPhraseSecretName", - "type": "Microsoft.Common.TextBox", - "visible": "true", - "label": "The name of the secret in the specified Key Vault whose value is the passphrase for the Trust KeyStore", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - } - }, - { - "name": "keyVaultCustomTrustKeyStoreType", - "type": "Microsoft.Common.DropDown", - "visible": "true", - "label": "The Trust KeyStore type (JKS,PKCS12)", - "defaultValue": "JKS", - "toolTip": "One of the supported KeyStore types", - "constraints": { - "allowedValues": [ - { - "label": "JKS", - "value": "JKS" - }, - { - "label": "PKCS12", - "value": "PKCS12" - } - ], - "required": true - } - } - ] - } - ] - }, - { - "name": "section_ohs", - "type": "Microsoft.Common.Section", - "label": "Oracle HTTP Server Load Balancer", - "elements": [ - { - "name": "connectToOHSext", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "Selecting 'Yes' here will cause the template to provision an Azure Oracle HTTP Server, set up a public IP, and configuration with WebLogic cluster address. Further configuration may be necessary after deployment.", - "link": { - "label": "Learn more", - "uri": "https://docs.oracle.com/en/middleware/fusion-middleware/web-tier/12.2.1.4/index.html" - } - } - }, - { - "name": "enableOHS", - "type": "Microsoft.Common.OptionsGroup", - "label": "Connect to Oracle HTTP Server?", - "defaultValue": "No", - "toolTip": "Select 'Yes' to cause an Azure Oracle HTTP Server to be created as the load balancer for the cluster.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": true - }, - { - "label": "No", - "value": false - } - ], - "required": false - } - }, - { - "name": "keyVaultText", - "type": "Microsoft.Common.TextBlock", - "visible": "[steps('section_ohs').enableOHS]", - "options": { - "text": "Oracle HTTP Server integration requires a TLS/SSL certificate to enable TLS/SSL termination. End-to-end TLS/SSL encryption is not supported by the template. The template will look for the certificate and its password in the Azure Key Vault specified here.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-dynamic-cluster-ohs" - } - } - }, - { - "name": "ohsSkuUrnVersion", - "type": "Microsoft.Common.DropDown", - "label": "Oracle HTTP Server image", - "defaultValue": "OHS 12.2.1.4.0 and JDK8 on Oracle Linux 7.6", - "toolTip": "Choose Oracle HTTP Server image, which is provided by Oracle, with Java and HTTP Server preinstalled.", - "constraints": { - "allowedValues": [ - { - "label": "OHS 12.2.1.4.0 and JDK8 on Oracle Linux 7.3", - "value": "ohs-122140-jdk8-ol73;ohs-122140-jdk8-ol73;latest" - }, - { - "label": "OHS 12.2.1.4.0 and JDK8 on Oracle Linux 7.4", - "value": "ohs-122140-jdk8-ol74;ohs-122140-jdk8-ol74;latest" - }, - { - "label": "OHS 12.2.1.4.0 and JDK8 on Oracle Linux 7.6", - "value": "ohs-122140-jdk8-ol76;ohs-122140-jdk8-ol76;latest" - } - ] - }, - "visible": "[steps('section_ohs').enableOHS]" - }, - { - "name": "ohsDomainName", - "type": "Microsoft.Common.TextBox", - "label": "Oracle HTTP Server Domain name", - "defaultValue": "ohsStandaloneDomain", - "toolTip": "Oracle HTTP Server Domain Name", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1}){1,2}$", - "validationMessage": "[if(greater(length(steps('section_ohs').ohsDomainName), 90),'Must be less than 90 characters.', 'Value only allows alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" - }, - "visible": "[steps('section_ohs').enableOHS]" - }, - { - "name": "ohsComponentName", - "type": "Microsoft.Common.TextBox", - "label": "Oracle HTTP Server Component name", - "defaultValue": "ohs_component", - "toolTip": "Oracle HTTP Server Component name", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1}){1,2}$", - "validationMessage": "[if(greater(length(steps('section_ohs').ohsDomainName), 90),'Must be less than 90 characters.', 'Value only allows alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" - }, - "visible": "[steps('section_ohs').enableOHS]" - }, - { - "name": "ohsNMUser", - "type": "Microsoft.Common.TextBox", - "label": "Oracle HTTP Server NodeManager username", - "defaultValue": "", - "toolTip": "Oracle HTTP Server NodeManager username", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1}){1,2}$", - "validationMessage": "[if(greater(length(steps('section_ohs').ohsDomainName), 90),'Must be less than 90 characters.', 'Value only allows alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" - }, - "visible": "[steps('section_ohs').enableOHS]" - }, - { - "name": "ohsNMPassword", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Oracle HTTP Server NodeManager Password", - "confirmPassword": "Confirm password" - }, - "toolTip": "Oracle HTTP Server NodeManager password", - "constraints": { - "required": true, - "regex": "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)[A-Za-z\\d]{12,}$", - "validationMessage": "The password must contain at least 12 characters, with at least 1 uppercase letter, 1 lowercase letter and 1 number, and special characters are not allowed." - }, - "options": { - "hideConfirmation": false - }, - "visible": "[steps('section_ohs').enableOHS]" - }, - { - "name": "ohshttpPort", - "type": "Microsoft.Common.TextBox", - "label": "Oracle HTTP Server HTTP port", - "defaultValue": "7777", - "toolTip": "Oracle HTTP Server HTTP port", - "constraints": { - "required": true, - "regex": "^[0-9]{2,5}$", - "validationMessage": "[if(greater(length(steps('section_ohs').ohshttpPort), 90),'Resource group names only allow up to 90 characters.', 'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" - }, - "visible": "[steps('section_ohs').enableOHS]" - }, - { - "name": "ohshttpsPort", - "type": "Microsoft.Common.TextBox", - "label": "Oracle HTTP Server HTTPS port", - "defaultValue": "4444", - "toolTip": "Oracle HTTP Server HTTPS port", - "constraints": { - "required": true, - "regex": "^[0-9]{2,5}$", - "validationMessage": "[if(greater(length(steps('section_ohs').ohshttpsPort), 90),'Resource group names only allow up to 90 characters.', 'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" - }, - "visible": "[steps('section_ohs').enableOHS]" - }, - { - "name": "oracleVaultPswd", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Oracle Vault Password", - "confirmPassword": "Confirm password" - }, - "toolTip": "The password to configure SSL store Oracle Vault", - "constraints": { - "required": true, - "regex": "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)[A-Za-z\\d]{12,}$", - "validationMessage": "The password must contain at least 12 characters, with at least 1 uppercase letter, 1 lowercase letter and 1 number, and special characters are not allowed." - }, - "options": { - "hideConfirmation": false - }, - "visible": "[steps('section_ohs').enableOHS]" - }, - { - "name": "ohsSSLConfigAccessOption", - "type": "Microsoft.Common.OptionsGroup", - "visible": "[steps('section_ohs').enableOHS]", - "label": "How would you like to provide required configuration", - "defaultValue": "Upload existing KeyStores", - "toolTip": "Select 'Upload existing KeyStores' to use local stored KeyStores.", - "constraints": { - "allowedValues": [ - { - "label": "Upload existing KeyStores", - "value": "uploadConfig" - }, - { - "label": "Use KeyStores stored in Azure Key Vault", - "value": "keyVaultStoredConfig" - } - ], - "required": false - } - }, - { - "name": "uploadedCustomSSLSettings", - "type": "Microsoft.Common.Section", - "visible": "[and(steps('section_ohs').enableOHS, equals(steps('section_ohs').ohsSSLConfigAccessOption, 'uploadConfig'))]", - "label": "TLS/SSL Configuration Settings", - "elements": [ - { - "name": "uploadedKeyStoreData", - "type": "Microsoft.Common.FileUpload", - "label": "TLS/SSL certificate Data file(.jks,.p12)", - "toolTip": "KeyStore for TLS/SSL configuration", - "constraints": { - "required": true, - "accept": ".jks,.p12" - }, - "options": { - "multiple": false, - "uploadMode": "file", - "openMode": "binary" - }, - "visible": true - }, - { - "name": "uploadedKeyStorePassword", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Password", - "confirmPassword": "Confirm password" - }, - "toolTip": " The password for the TLS/SSL certificate Data", - "constraints": { - "required": true, - "regex": "^.{6,}$", - "validationMessage": "Keypass must be at least 6 characters long." - }, - "options": { - "hideConfirmation": false - }, - "visible": true - }, - { - "name": "uploadedKeyStoreType", - "type": "Microsoft.Common.DropDown", - "visible": "true", - "label": "Type of the certificate format(JKS,PKCS12)", - "defaultValue": "JKS", - "toolTip": "One of the supported KeyStore types", - "constraints": { - "allowedValues": [ - { - "label": "JKS", - "value": "JKS" - }, - { - "label": "PKCS12", - "value": "PKCS12" - } - ], - "required": true - } - } - ] - }, - { - "name": "keyVaultStoredCustomSSLSettings", - "type": "Microsoft.Common.Section", - "visible": "[and(steps('section_ohs').enableOHS, equals(steps('section_ohs').ohsSSLConfigAccessOption, 'keyVaultStoredConfig'))]", - "label": "TLS/SSL Configuration Settings", - "elements": [ - { - "name": "keyType", - "type": "Microsoft.Common.DropDown", - "label": "Certificate Type", - "defaultValue": "JKS", - "toolTip": "One of the supported KeyStore types", - "constraints": { - "allowedValues": [ - { - "label": "PKCS12", - "value": "PKCS12" - }, - { - "label": "JKS", - "value": "JKS" - } - ], - "required": false - }, - "visible": true - }, - { - "name": "keyVaultResourceGroup", - "type": "Microsoft.Common.TextBox", - "label": "Resource group name in current subscription containing the Key Vault", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1}){1,2}$", - "validationMessage": "[if(greater(length(steps('section_ohs').ohsDomainName), 90),'Must be less than 90 characters.', 'Value only allows alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" - }, - "visible": true - }, - { - "name": "keyVaultName", - "type": "Microsoft.Common.TextBox", - "label": "Name of the Azure Key Vault containing secrets for the certificate for TLS/SSL Termination", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^(?=.{3,24}$)[a-zA-Z](([a-z0-9A-Z]*|(?:\\-[^\\-][a-z0-9A-Z]*))*)$", - "validationMessage": "[if(or(greater(length(steps('section_ohs').keyVaultName), 24), less(length(steps('section_ohs').keyVaultName), 3)),'Vault name must be between 3-24 alphanumeric characters. The name must begin with a letter, end with a letter or digit, and not contain consecutive hyphens.','Vault name must only contain alphanumeric characters and dashes and cannot start with a number')]" - }, - "visible": true - }, - { - "name": "keyVaultSSLCertDataSecretName", - "type": "Microsoft.Common.TextBox", - "label": "The name of the secret in the specified Key Vault whose value is the TLS/SSL certificate Data", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - }, - "visible": true - }, - { - "name": "keyVaultSSLCertPasswordSecretName", - "type": "Microsoft.Common.TextBox", - "label": "The name of the secret in the specified Key Vault whose value is the password for the TLS/SSL certificate", - "defaultValue": "", - "toolTip": "Use only letters and numbers", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." - }, - "visible": true - } - ] - }, - { - "name": "denyPublicTrafficForManagedServer", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deny public traffic for managed server?", - "defaultValue": "Yes", - "toolTip": "Select 'Yes' to deny public traffic for managed server. Configuration here for port 8002 ~ 8001 + 'node number' has a higher priority than the 'Ports and port ranges to expose' in basic blade.", - "constraints": { - "allowedValues": [ - { - "label": "No", - "value": false - }, - { - "label": "Yes", - "value": true - } - ], - "required": true - }, - "visible": "[steps('section_ohs').enableOHS]" - } - ], - "visible": true - }, - { - "name": "section_dnsConfiguration", - "type": "Microsoft.Common.Section", - "label": "DNS Configuration", - "elements": [ - { - "name": "dnsConfigurationText", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "Selecting 'Yes' here will cause the template to provision Load Balancer and Oracle WebLogic Administration Console using custom DNS Name (example: console.contoso.com)", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-dns" - } - } - }, - { - "name": "enableCustomDNS", - "type": "Microsoft.Common.OptionsGroup", - "visible": true, - "label": "Configure Custom DNS Alias?", - "defaultValue": "No", - "toolTip": "Select 'Yes' to configure Custom DNS Alias.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": true - }, - { - "label": "No", - "value": false - } - ], - "required": false - } - }, - { - "name": "customDNSSettings", - "type": "Microsoft.Common.Section", - "label": "DNS Configuration Settings", - "visible": "[bool(steps('section_dnsConfiguration').enableCustomDNS)]", - "elements": [ - { - "name": "bringDNSZone", - "type": "Microsoft.Common.OptionsGroup", - "label": "Use an existing Azure DNS Zone", - "defaultValue": "No", - "toolTip": "Select 'Yes' to configure Custom DNS Alias based on an existing Azure DNS Zone. Select 'No' to create an Azure DNS Zone and Custom DNS Alias.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": true - }, - { - "label": "No", - "value": false - } - ] - } - }, - { - "name": "createDNSZoneText", - "type": "Microsoft.Common.InfoBox", - "visible": "[not(bool(steps('section_dnsConfiguration').customDNSSettings.bringDNSZone))]", - "options": { - "icon": "Info", - "text": "You must perform DNS Domain Delegation at your DNS Registry after deployment.", - "uri": "https://aka.ms/dns-domain-delegation" - } - }, - { - "name": "deplymentScriptInfo", - "type": "Microsoft.Common.TextBlock", - "options": { - "text": "If you choose to use an existing Azure DNS Zone, you must select a user-assigned managed identity to enable the necessary configuration." - }, - "visible": "[steps('section_dnsConfiguration').customDNSSettings.bringDNSZone]" - }, - { - "name": "dnszoneName", - "type": "Microsoft.Common.TextBox", - "label": "DNS Zone Name", - "defaultValue": "", - "toolTip": "Use only letters and numbers and periods to separate Domains", - "constraints": { - "required": true, - "regex": "^([0-9a-zA-Z_-]{1,63}\\.){1,33}[0-9a-zA-Z_-]{1,63}$", - "validationMessage": "There must be between 2 and 34 labels. For example, \"contoso.com\" has 2 labels. Each label must contain between 1 and 63 characters. Each label must only contain letters, numbers, underscores, and dashes." - } - }, - { - "name": "dnsZoneResourceGroup", - "type": "Microsoft.Common.TextBox", - "label": "Name of the resource group contains the DNS Zone in current subscription", - "defaultValue": "", - "toolTip": "Name of the resource group contains the DNS Zone in current subscription", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1})$", - "validationMessage": "[if(greater(length(steps('section_dnsConfiguration').existingDNSZonesSettings.dnsZoneResourceGroup), 90),'Resource group names only allow up to 90 characters.', 'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" - }, - "visible": "[steps('section_dnsConfiguration').customDNSSettings.bringDNSZone]" - }, - { - "name": "dnszoneAdminConsoleLabel", - "type": "Microsoft.Common.TextBox", - "label": "Label for Oracle WebLogic Administration Console", - "defaultValue": "admin", - "toolTip": "Specify a label to generate subdomain of Oracle WebLogic Administration Console", - "constraints": { - "required": true, - "validations": [ - { - "regex": "^([0-9a-zA-Z_-]{1,63}\\.){0,33}[0-9a-zA-Z_-]{1,63}$", - "message": "Each label must contain between 1 and 63 characters. Each label must only contain letters, numbers, underscores, and dashes." - }, - { - "isValid": "[less(sub(length(concat(steps('section_dnsConfiguration').customDNSSettings.dnszoneAdminConsoleLabel,'.',steps('section_dnsConfiguration').customDNSSettings.dnszoneName)),length(replace(concat(steps('section_dnsConfiguration').customDNSSettings.dnszoneAdminConsoleLabel,'.',steps('section_dnsConfiguration').customDNSSettings.dnszoneName), '.', ''))),34)]", - "message": "Subdomain must be between 2 and 34 labels. For example, \"admin.contoso.com\" has 3 labels." - } - ] - } - }, - { - "name": "dnszoneLoadBalancerLabel", - "type": "Microsoft.Common.TextBox", - "label": "Label for Load Balancer", - "defaultValue": "www", - "toolTip": "Specify a label to generate subdomain of Load Balancer", - "constraints": { - "required": true, - "validations": [ - { - "regex": "^([0-9a-zA-Z_-]{1,63}\\.){0,33}[0-9a-zA-Z_-]{1,63}$", - "message": "Each label must contain between 1 and 63 characters. Each label must only contain letters, numbers, underscores, and dashes." - }, - { - "isValid": "[less(sub(length(concat(if(empty(steps('section_dnsConfiguration').customDNSSettings.dnszoneLoadBalancerLabel), '', steps('section_dnsConfiguration').customDNSSettings.dnszoneLoadBalancerLabel),'.',steps('section_dnsConfiguration').customDNSSettings.dnszoneName)),length(replace(concat(if(empty(steps('section_dnsConfiguration').customDNSSettings.dnszoneLoadBalancerLabel), '', steps('section_dnsConfiguration').customDNSSettings.dnszoneLoadBalancerLabel),'.',steps('section_dnsConfiguration').customDNSSettings.dnszoneName), '.', ''))),34)]", - "message": "Subdomain must be between 2 and 34 labels. For example, \"applications.contoso.com\" has 3 labels." - } - ] - }, - "visible": "[and(bool(steps('section_ohs').enableOHS), bool(steps('section_dnsConfiguration').enableCustomDNS))]" - }, - { - "name": "infoDNSIndentity", - "type": "Microsoft.Common.InfoBox", - "visible": "[and(bool(steps('section_dnsConfiguration').customDNSSettings.bringDNSZone), less(length(steps('section_dnsConfiguration').customDNSSettings.dnsIdentity.userAssignedIdentities), 1))]", - "options": { - "icon": "Error", - "text": "This option will use Azure deployment scripts to update records to your Azure DNS Zone. You have to add at least one user-assigned identity to access Azure resources.", - "uri": "https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/deployment-script-template" - } - }, - { - "name": "dnsIdentity", - "type": "Microsoft.ManagedIdentity.IdentitySelector", - "label": "Managed Identity Configuration", - "toolTip": { - "userAssignedIdentity": "Add user-assigned identities to grant the resource access to Azure resources." - }, - "defaultValue": { - "systemAssignedIdentity": "Off" - }, - "options": { - "hideSystemAssignedIdentity": true, - "hideUserAssignedIdentity": false - }, - "visible": "[bool(steps('section_dnsConfiguration').customDNSSettings.bringDNSZone)]" - } - ] - } - ] - }, - { - "name": "section_database", - "type": "Microsoft.Common.Section", - "label": "Database", - "subLabel": { - "preValidation": "Configure integrations to Azure services", - "postValidation": "Done" - }, - "bladeTitle": "Service Integrations", - "elements": [ - { - "name": "aboutDatabase", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "Selecting 'Yes' here and providing the configuration will cause the template to configure the WebLogic Server to connect to the desired pre-existing database. The database must be network accessible to the VNET and subnets created by the template." - } - }, - { - "name": "enableDB", - "type": "Microsoft.Common.OptionsGroup", - "label": "Connect to database?", - "defaultValue": "No", - "toolTip": "Select 'Yes' and provide required info to configure the connection to a database.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": "true" - }, - { - "label": "No", - "value": "false" - } - ], - "required": true - } - }, - { - "name": "databaseConnectionInfo", - "type": "Microsoft.Common.Section", - "label": "Connection settings", - "elements": [ - { - "name": "databaseType", - "type": "Microsoft.Common.DropDown", - "label": "Choose database type", - "toolTip": "Choose database type", - "defaultValue": "Oracle database", - "constraints": { - "allowedValues": [ - { - "label": "Azure database for PostgreSQL", - "value": "postgresql" - }, - { - "label": "Oracle database", - "value": "oracle" - }, - { - "label": "Azure SQL", - "value": "sqlserver" - } - ], - "required": true - }, - "visible": true - }, - { - "name": "jdbcDataSourceName", - "type": "Microsoft.Common.TextBox", - "label": "JNDI Name", - "toolTip": "The JNDI name for the database JDBC connection", - "defaultValue": "", - "constraints": { - "required": "[bool(steps('section_database').enableDB)]", - "regex": "^[a-z0-9A-Z/]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters, numbers, and slashes (/)." - }, - "visible": true - }, - { - "name": "dsConnectionURL", - "type": "Microsoft.Common.TextBox", - "label": "DataSource Connection String", - "toolTip": "The JDBC connection string for the database", - "defaultValue": "", - "constraints": { - "required": "[bool(steps('section_database').enableDB)]", - "regex": "[concat('^jdbc:', coalesce(steps('section_database').databaseConnectionInfo.databaseType, ''), '.*$')]", - "validationMessage": "A valid JDBC URL for the chosen database type must be provided" - }, - "visible": true - }, - { - "name": "dbUser", - "type": "Microsoft.Common.TextBox", - "label": "Database username", - "toolTip": "Use only letters and numbers", - "defaultValue": "", - "constraints": { - "required": "[bool(steps('section_database').enableDB)]", - "regex": "^(?=.{1,128}$)(?!\\-)([a-z0-9A-Z@\\-]){1,128}([^\\-])$", - "validationMessage": "The value must be 1-128 characters long and must only contain letters, numbers, hyphen(-) and the at sign, no hyphen allowed at the beginning and the end of database username." - }, - "visible": true - }, - { - "name": "dbPassword", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Database Password", - "confirmPassword": "Confirm password" - }, - "toolTip": "Database Password", - "constraints": { - "required": "[bool(steps('section_database').enableDB)]", - "regex": "^((?=.*[0-9])(?=.*[a-zA-Z!@#$%^&*])).{5,128}$", - "validationMessage": "The password must be between five and 128 characters long and have at least one number." - }, - "options": { - "hideConfirmation": false - }, - "visible": true - } - ], - "visible": "[bool(steps('section_database').enableDB)]" - } - ] - }, - { - "name": "section_aad", - "label": "Azure Active Directory", - "subLabel": { - "preValidation": "Configure the connection to Azure Active Directory.", - "postValidation": "Done" - }, - "bladeTitle": "Azure Active Directory", - "elements": [ - { - "name": "aboutAad", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "icon": "None", - "text": "Selecting 'Yes' here and providing the configuration will cause the template to configure the connection to Azure Active Directory.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-cluster-aad-ldap" - } - } - }, - { - "name": "enableAAD", - "type": "Microsoft.Common.OptionsGroup", - "label": "Connect to Azure Active Directory?", - "defaultValue": "No", - "toolTip": "Select 'Yes' and provide required info to configure the connection to Azure Active Directory.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": "true" - }, - { - "label": "No", - "value": "false" - } - ], - "required": true - } - }, - { - "name": "aadInfo", - "type": "Microsoft.Common.Section", - "label": "Connection settings", - "elements": [ - { - "name": "aadsServerHost", - "type": "Microsoft.Common.TextBox", - "label": "Server Host", - "toolTip": "The LDAP server host.", - "defaultValue": "", - "constraints": { - "required": true, - "regex": "(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]", - "validationMessage": "The value must be a valid host name." - } - }, - { - "name": "aadsPublicIP", - "type": "Microsoft.Common.TextBox", - "label": "Secure LDAP external IP address", - "toolTip": "Secure LDAP external IP address.", - "constraints": { - "required": true, - "regex": "\\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.|$)){4}\\b", - "validationMessage": "The value must be a valid IP address." - } - }, - { - "name": "aadsPortNumber", - "type": "Microsoft.Common.TextBox", - "label": "Port", - "toolTip": "The port number of LDAP Server, default is 636.", - "defaultValue": "636", - "constraints": { - "required": true, - "regex": "^[0-9]+$", - "validationMessage": "The value must be numbers." - } - }, - { - "name": "wlsLDAPProviderName", - "type": "Microsoft.Common.TextBox", - "label": "Provider Name", - "defaultValue": "AzureActiveDirectoryProvider", - "toolTip": "The value used for creating authentication provider name of WebLogic Server.", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z]{3,50}$", - "validationMessage": "The Provider Name must be between 3 and 50 characters long and contain letters, numbers only." - } - }, - { - "name": "wlsLDAPPrincipal", - "type": "Microsoft.Common.TextBox", - "label": "Principal", - "toolTip": "The Distinguished Name (DN) of the LDAP user that WebLogic Server should use to connect to the LDAP server.", - "constraints": { - "required": true, - "regex": ".+,dc|DC=([^,]+),dc|DC=([^,]+)$", - "validationMessage": "The value must be valid LDAP user distinguished name." - } - }, - { - "name": "wlsLDAPPrincipalPassword", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Password for Principal", - "confirmPassword": "Confirm password" - }, - "toolTip": "The credential (usually a password) used to connect to the LDAP server.", - "constraints": { - "required": true - } - }, - { - "name": "wlsLDAPUserBaseDN", - "type": "Microsoft.Common.TextBox", - "label": "User Base DN", - "toolTip": "The base distinguished name (DN) of the tree in the LDAP directory that contains users.", - "constraints": { - "required": true, - "regex": ".+,dc|DC=([^,]+),dc|DC=([^,]+)$", - "validationMessage": "The value must be valid LDAP user based distinguished name." - } - }, - { - "name": "wlsLDAPGroupBaseDN", - "type": "Microsoft.Common.TextBox", - "label": "Group Base DN", - "toolTip": "The base distinguished name (DN) of the tree in the LDAP directory that contains groups.", - "constraints": { - "required": true, - "regex": ".+,dc|DC=([^,]+),dc|DC=([^,]+)$", - "validationMessage": "The value must be valid LDAP group based distinguished name." - } - }, - { - "name": "wlsLDAPSSLCertificate", - "type": "Microsoft.Common.FileUpload", - "label": "Client certificate for TLS/SSL Configuration (.cer)", - "toolTip": "Client certificate of AAD LDAP server, used to configure the Trust Keystore to enable TLS/SSL in Oracle WebLogic Server.", - "constraints": { - "required": true, - "accept": ".cer" - }, - "options": { - "multiple": false, - "uploadMode": "file", - "openMode": "binary" - } - } - ], - "visible": "[bool(steps('section_aad').enableAAD)]" - } - ] - }, - { - "name": "section_elk", - "label": "Elasticsearch and Kibana", - "subLabel": { - "preValidation": "Configure the connection to Elasticsearch and Kibana.", - "postValidation": "Done" - }, - "bladeTitle": "Elasticsearch and Kibana", - "elements": [ - { - "name": "aboutelk", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "icon": "None", - "text": "Selecting 'Yes' here and providing the configuration will cause the template to configure Elasticsearch and Kibana to store WLS logs.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-elk-tutorial" - } - } - }, - { - "name": "enableELK", - "type": "Microsoft.Common.OptionsGroup", - "label": "Export logs to Elasticsearch?", - "defaultValue": "No", - "toolTip": "Select 'Yes' and provide required info to configure the connection to Elasticsearch.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": "true" - }, - { - "label": "No", - "value": "false" - } - ], - "required": true - } - }, - { - "name": "elkInfo", - "type": "Microsoft.Common.Section", - "label": "Connection settings", - "elements": [ - { - "name": "elkMemoryRequiredText", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "icon": "None", - "text": "To ensure Logstash works correctly, the selected Virtual Machines have at least 2.5GB memory.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-elk" - } - } - }, - { - "name": "elkMemoryRequired", - "type": "Microsoft.Common.InfoBox", - "options": { - "icon": "Error", - "text": "Your selected Virtual Machines have less than 2.5GB memory to set up Elasticsearch and Kibana, please go to Basics -> Virtual machine size to change it, recommended size is Standard_A2_v2." - }, - "visible": "[and(contains('Standard_A1,Basic_A1,Standard_B1ms,Standard_A1_v2,Standard_F1,Standard_F1s', basics('vmSizeSelect')),bool(steps('section_elk').enableELK))]" - }, - { - "name": "elasticsearchEndpoint", - "type": "Microsoft.Common.TextBox", - "label": "Elasticsearch endpoint URL", - "toolTip": "Elasticsearch endpoint.", - "defaultValue": "https://example.location.azure.elastic-cloud.com:9243", - "constraints": { - "required": true, - "validations": [ - { - "regex": "^https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*):[0-9]{1,6}$", - "message": "The value must be a valid endpoint." - }, - { - "isValid": "[not(contains('Standard_A1,Basic_A1,Standard_B1ms,Standard_A1_v2,Standard_F1,Standard_F1s', basics('vmSizeSelect')))]", - "message": "Your selected Virtual Machines have less than 2.5GB memory to set up Elasticsearch and Kibana, please go to Basics -> Virtual machine size to change it, recommended size is Standard_A2_v2." - } - ] - } - }, - { - "name": "elasticsearchUserName", - "type": "Microsoft.Common.TextBox", - "label": "Elasticsearch User Name", - "defaultValue": "elastic", - "toolTip": "User name of Elasticsearch account.", - "constraints": { - "required": true, - "regex": "^(?!\\-)([a-z0-9A-Z@\\-]{1,128})([^\\-])", - "validationMessage": "The value must be valid Elasticsearch user name." - } - }, - { - "name": "elasticsearchPassword", - "type": "Microsoft.Common.PasswordBox", - "label": { - "password": "Password for Elasticsearch account", - "confirmPassword": "Confirm password" - }, - "toolTip": "Password of Elasticsearch account.", - "constraints": { - "required": true - } - }, - { - "name": "logsToIntegrate", - "type": "Microsoft.Common.DropDown", - "label": "WebLogic Server logs to export", - "toolTip": "The logs selected will be exported to Elasticsearch.", - "defaultValue": [ - "Server Log" - ], - "multiselect": true, - "selectAll": true, - "multiLine": true, - "defaultDescription": "The logs selected will be exported to Elasticsearch", - "constraints": { - "allowedValues": [ - { - "label": "Data Source Log", - "description": "Export Datasource logs to Elasticsearch.", - "value": "DataSourceLog" - }, - { - "label": "Domain Log", - "description": "Export Domain logs to Elasticsearch.", - "value": "DomainLog" - }, - { - "label": "HTTP Access Log", - "description": "Export HTTP logs to Elasticsearch.", - "value": "HTTPAccessLog" - }, - { - "label": "Node Manager Logs", - "description": "Export Node Manager logs to Elasticsearch.", - "value": "NodeManagerLog" - }, - { - "label": "Server Log", - "description": "Export Server logs to Elasticsearch.", - "value": "ServerLog" - }, - { - "label": "Standard error and output", - "description": "Export standard error and output to Elasticsearch.", - "value": "StandardErrorAndOutput" - } - ], - "required": true - } - } - ], - "visible": "[bool(steps('section_elk').enableELK)]" - } - ] - }, - { - "name": "section_coherence", - "label": "Coherence", - "subLabel": { - "preValidation": "Configure Coherence.", - "postValidation": "Done" - }, - "bladeTitle": "Coherence", - "elements": [ - { - "name": "aboutCoherence", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "icon": "None", - "text": "Selecting 'Yes' here and providing the configuration will cause the template to create a Coherence cluster, the WebLogic Domain will create a data tier configured with Managed Coherence cache servers.", - "link": { - "label": "Learn more", - "uri": "https://aka.ms/arm-oraclelinux-wls-coherence" - } - } - }, - { - "name": "enableCoherence", - "type": "Microsoft.Common.OptionsGroup", - "label": "Use Coherence cache?", - "defaultValue": "No", - "toolTip": "Select 'Yes' and provide required info to configure Coherence cluster.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": "true" - }, - { - "label": "No", - "value": "false" - } - ], - "required": true - } - }, - { - "name": "coherenceInfo", - "type": "Microsoft.Common.Section", - "label": "Coherence settings", - "elements": [ - { - "name": "coherenceVMSizeSelect", - "type": "Microsoft.Compute.SizeSelector", - "label": "Coherence virtual machine size", - "toolTip": "The size of virtual machine for Coherence cache servers.", - "recommendedSizes": [ - "[basics('vmSizeSelect')]" - ], - "constraints": { - "excludedSizes": [ - "Standard_B1ls", - "Standard_A0", - "Basic_A0", - "Standard_B1s" - ] - }, - "osPlatform": "Linux", - "count": "1", - "visible": true - }, - { - "name": "numberOfCoherenceStorageInstances", - "type": "Microsoft.Common.TextBox", - "label": "Number of Coherence cache servers", - "toolTip": "Number of Coherence cache instances, used to create virtual machines and WebLogic Managed Server.", - "defaultValue": "1", - "constraints": { - "required": true, - "regex": "^[0-9]+$", - "validationMessage": "The value must be a valid number." - } - }, - { - "name": "enableCoherenceWebLocalStorage", - "type": "Microsoft.Common.OptionsGroup", - "label": "Coherence Web Local Storage Enabled", - "defaultValue": "Yes", - "toolTip": "Specifies whether Local Storage is enabled for the Coherence*Web cluster tier", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": "true" - }, - { - "label": "No", - "value": "false" - } - ], - "required": true - } - } - ], - "visible": "[bool(steps('section_coherence').enableCoherence)]" - } - ] - } - ], - "outputs": { - "Location": "[location()]", - "aadsPortNumber": "[steps('section_aad').aadInfo.aadsPortNumber]", - "aadsPublicIP": "[steps('section_aad').aadInfo.aadsPublicIP]", - "aadsServerHost": "[steps('section_aad').aadInfo.aadsServerHost]", - "adminPasswordOrKey": "[if(equals(basics('basicsRequired').adminPasswordOrKey.authenticationType, 'password'), basics('basicsRequired').adminPasswordOrKey.password, basics('basicsRequired').adminPasswordOrKey.sshPublicKey)]", - "adminUsername": "[basics('basicsRequired').adminUsername]", - "authenticationType": "[basics('basicsRequired').adminPasswordOrKey.authenticationType]", - "databaseType": "[steps('section_database').databaseConnectionInfo.databaseType]", - "denyPublicTrafficForAdminServer": "[basics('basicsOptional').denyPublicTrafficForAdminServer]", - "denyPublicTrafficForManagedServer": "[steps('section_ohs').denyPublicTrafficForManagedServer]", - "dnsLabelPrefix": "[basics('basicsOptional').dnsLabelPrefix]", - "dsConnectionURL": "[steps('section_database').databaseConnectionInfo.dsConnectionURL]", - "dnszoneIdentity": "[steps('section_dnsConfiguration').customDNSSettings.dnsIdentity]", - "dnszoneName": "[steps('section_dnsConfiguration').customDNSSettings.dnszoneName]", - "dnszoneResourceGroup": "[steps('section_dnsConfiguration').customDNSSettings.dnsZoneResourceGroup]", - "dnszoneAdminConsoleLabel": "[steps('section_dnsConfiguration').customDNSSettings.dnszoneAdminConsoleLabel]", - "dnszoneLoadBalancerLabel": "[steps('section_dnsConfiguration').customDNSSettings.dnszoneLoadBalancerLabel]", - "dbPassword": "[steps('section_database').databaseConnectionInfo.dbPassword]", - "dbUser": "[steps('section_database').databaseConnectionInfo.dbUser]", - "elasticsearchEndpoint": "[steps('section_elk').elkInfo.elasticsearchEndpoint]", - "elasticsearchPassword": "[steps('section_elk').elkInfo.elasticsearchPassword]", - "elasticsearchUserName": "[steps('section_elk').elkInfo.elasticsearchUserName]", - "dynamicClusterSize": "[int(basics('basicsRequired').dynamicClusterSize)]", - "enableAAD": "[bool(steps('section_aad').enableAAD)]", - "enableCoherence": "[bool(steps('section_coherence').enableCoherence)]", - "enableCoherenceWebLocalStorage": "[bool(if(bool(steps('section_coherence').enableCoherence),steps('section_coherence').coherenceInfo.enableCoherenceWebLocalStorage,'false'))]", - "enableDB": "[bool(steps('section_database').enableDB)]", - "enableCustomDNS": "[bool(steps('section_dnsConfiguration').enableCustomDNS)]", - "enableELK": "[bool(steps('section_elk').enableELK)]", - "enableOHS": "[bool(steps('section_ohs').enableOHS)]", - "hasDNSZones": "[bool(if(bool(steps('section_dnsConfiguration').enableCustomDNS), steps('section_dnsConfiguration').customDNSSettings.bringDNSZone, 'false'))]", - "jdbcDataSourceName": "[steps('section_database').databaseConnectionInfo.jdbcDataSourceName]", - "logsToIntegrate": "[steps('section_elk').elkInfo.logsToIntegrate]", - "managedServerPrefix": "[basics('basicsOptional').managedServerPrefix]", - "maxDynamicClusterSize": "[int(basics('basicsRequired').maxDynamicClusterSize)]", - "numberOfCoherenceCacheInstances": "[int(if(bool(steps('section_coherence').enableCoherence),steps('section_coherence').coherenceInfo.numberOfCoherenceStorageInstances,'1'))]", - "portsToExpose": "[basics('basicsOptional').portsToExpose]", - "skuUrnVersion": "[basics('skuUrnVersion')]", - "useSystemAssignedManagedIdentity": "[basics('basicsOptional').useSystemAssignedManagedIdentity]", - "vmSizeSelect": "[basics('vmSizeSelect')]", - "vmSizeSelectForCoherence": "[steps('section_coherence').coherenceInfo.coherenceVMSizeSelect]", - "wlsDomainName": "[basics('basicsOptional').wlsDomainName]", - "wlsLDAPGroupBaseDN": "[steps('section_aad').aadInfo.wlsLDAPGroupBaseDN]", - "wlsLDAPPrincipal": "[steps('section_aad').aadInfo.wlsLDAPPrincipal]", - "wlsLDAPPrincipalPassword": "[steps('section_aad').aadInfo.wlsLDAPPrincipalPassword]", - "wlsLDAPProviderName": "[steps('section_aad').aadInfo.wlsLDAPProviderName]", - "wlsLDAPSSLCertificate": "[steps('section_aad').aadInfo.wlsLDAPSSLCertificate]", - "wlsLDAPUserBaseDN": "[steps('section_aad').aadInfo.wlsLDAPUserBaseDN]", - "wlsPassword": "[basics('basicsRequired').wlsPassword]", - "wlsUserName": "[basics('basicsRequired').wlsUserName]", - "ohsSkuUrnVersion": "[steps('section_ohs').ohsSkuUrnVersion]", - "ohsDomainName": "[steps('section_ohs').ohsDomainName]", - "ohsComponentName": "[steps('section_ohs').ohsComponentName]", - "ohsNMUser": "[steps('section_ohs').ohsNMUser]", - "ohsNMPassword": "[steps('section_ohs').ohsNMPassword]", - "ohshttpPort": "[steps('section_ohs').ohshttpPort]", - "ohshttpsPort": "[steps('section_ohs').ohshttpsPort]", - "oracleVaultPswd": "[steps('section_ohs').oracleVaultPswd]", - "enableHTTPAdminListenPort": "[basics('basicsOptional').enableAdminHTTPListenPort]", - "enableCustomSSL": "[steps('section_sslConfiguration').enableCustomSSL]", - "sslConfigurationAccessOption": "[steps('section_sslConfiguration').sslConfigurationAccessOption]", - "adminSSLKeyVaultResourceGroup": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultResourceGroup]", - "adminSSLKeyVaultName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultName]", - "keyVaultCustomIdentityKeyStoreDataSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomIdentityKeyStoreDataSecretName]", - "keyVaultCustomIdentityKeyStorePassPhraseSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomIdentityKeyStorePassPhraseSecretName]", - "keyVaultCustomIdentityKeyStoreType": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomIdentityKeyStoreType]", - "keyVaultCustomTrustKeyStoreDataSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomTrustKeyStoreDataSecretName]", - "keyVaultCustomTrustKeyStorePassPhraseSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomTrustKeyStorePassPhraseSecretName]", - "keyVaultCustomTrustKeyStoreType": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultCustomTrustKeyStoreType]", - "keyVaultPrivateKeyAliasSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultPrivateKeyAliasSecretName]", - "keyVaultPrivateKeyPassPhraseSecretName": "[steps('section_sslConfiguration').keyVaultStoredCustomSSLSettings.keyVaultPrivateKeyPassPhraseSecretName]", - "uploadedCustomIdentityKeyStoreData": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomIdentityKeyStoreData]", - "uploadedCustomIdentityKeyStorePassphrase": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomIdentityKeyStorePassphrase]", - "uploadedCustomIdentityKeyStoreType": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomIdentityKeyStoreType]", - "uploadedCustomTrustKeyStoreData": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomTrustKeyStoreData]", - "uploadedCustomTrustKeyStorePassPhrase": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomTrustKeyStorePassPhrase]", - "uploadedCustomTrustKeyStoreType": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomTrustKeyStoreType]", - "uploadedPrivateKeyAlias": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedPrivateKeyAlias]", - "uploadedPrivateKeyPassPhrase": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedPrivateKeyPassPhrase]", - "ohsSSLConfigAccessOption": "[steps('section_ohs').ohsSSLConfigAccessOption]", - "uploadedKeyStoreData": "[steps('section_ohs').uploadedCustomSSLSettings.uploadedKeyStoreData]", - "uploadedKeyStorePassword": "[steps('section_ohs').uploadedCustomSSLSettings.uploadedKeyStorePassword]", - "uploadedKeyStoreType": "[steps('section_ohs').uploadedCustomSSLSettings.uploadedKeyStoreType]", - "keyType": "[steps('section_ohs').keyVaultStoredCustomSSLSettings.keyType]", - "keyVaultResourceGroup": "[steps('section_ohs').keyVaultStoredCustomSSLSettings.keyVaultResourceGroup]", - "keyVaultName": "[steps('section_ohs').keyVaultStoredCustomSSLSettings.keyVaultName]", - "keyVaultSSLCertDataSecretName": "[steps('section_ohs').keyVaultStoredCustomSSLSettings.keyVaultSSLCertDataSecretName]", - "keyVaultSSLCertPasswordSecretName": "[steps('section_ohs').keyVaultStoredCustomSSLSettings.keyVaultSSLCertPasswordSecretName]" - } - } -} +{ + "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", + "handler": "Microsoft.Azure.CreateUIDef", + "version": "0.1.2-preview", + "parameters": { + "config": { + "basics": { + "resourceGroup": { + "allowExisting": true + } + } + }, + "basics": [ + { + "name": "skuUrnVersion", + "type": "Microsoft.Common.DropDown", + "label": "Oracle WebLogic Image", + "defaultValue": "WebLogic Server 14.1.1.0.0 and JDK 11 on Oracle Linux 9.1", + "toolTip": "Choose Oracle WebLogic image, which is provided by Oracle, with Java and WebLogic preinstalled.", + "constraints": { + "allowedValues": [ + { + "label": "WebLogic Server 14.1.1.0.0 and JDK 11 on Oracle Linux 9.1", + "value": "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK 11 on Oracle Linux 8.7", + "value": "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK 8 on Oracle Linux 9.1", + "value": "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK 8 on Oracle Linux 8.7", + "value": "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest" + }, + { + "label": "WebLogic Server 12.2.1.4.0 and JDK 8 on Oracle Linux 9.1", + "value": "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest" + }, + { + "label": "WebLogic Server 12.2.1.4.0 and JDK 8 on Oracle Linux 8.7", + "value": "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest" + }, + { + "label": "WebLogic Server 12.2.1.4.0 and JDK8 on Oracle Linux 7.6", + "value": "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK8 on Oracle Linux 7.6", + "value": "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK11 on Oracle Linux 7.6", + "value": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK11 on Red Hat Enterprise Linux 8.7", + "value": "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK8 on Red Hat Enterprise Linux 8.7", + "value": "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest" + }, + { + "label": "WebLogic Server 12.2.1.4.0 and JDK8 on Red Hat Enterprise Linux 8.7", + "value": "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest" + } + ], + "required": true + }, + "visible": true + }, + { + "name": "vmSizeSelect", + "type": "Microsoft.Compute.SizeSelector", + "label": "Virtual machine size", + "toolTip": "The size of virtual machine to provision.", + "recommendedSizes": [ + "Standard_A1", + "Standard_A2", + "Standard_A3", + "Standard_A4", + "Standard_B1ms" + ], + "constraints": { + "excludedSizes": [ + "Standard_B1ls", + "Standard_A0", + "Basic_A0", + "Standard_B1s", + ${azure.armBased.vmSize.list} + ] + }, + "osPlatform": "Linux", + "count": "1", + "visible": true + }, + { + "name": "invalidVMSizeInfo", + "type": "Microsoft.Common.InfoBox", + "visible": "[contains(basics('vmSizeSelect'),'p')]", + "options": { + "icon": "Error", + "text": "The VM size you selected includes the feature letter 'p', indicating it uses ARM CPUs. ARM platform is not supported. Please select a different VM size. For more information, refer to the Azure virtual machine sizes naming conventions." + } + }, + { + "name": "basicsRequired", + "type": "Microsoft.Common.Section", + "label": "Credentials for Virtual Machines and WebLogic", + "elements": [ + { + "name": "adminUsername", + "type": "Microsoft.Common.TextBox", + "label": "Username for admin account of VMs", + "defaultValue": "weblogic", + "toolTip": "Use only letters and numbers", + "constraints": { + "required": true, + "validations": [ + { + "regex": "^[a-z0-9A-Z]{1,30}$", + "message": "The value must be 1-30 characters long and must only contain letters and numbers." + }, + { + "isValid": "[not(contains(basics('vmSizeSelect'),'p'))]", + "message": "ARM platform is not supported. Please select a different VM size." + } + ] + }, + "visible": true + }, + { + "name": "adminPasswordOrKey", + "type": "Microsoft.Compute.CredentialsCombo", + "label": { + "authenticationType": "Authentication type", + "password": "Password", + "confirmPassword": "Confirm password", + "sshPublicKey": "SSH public key" + }, + "toolTip": { + "authenticationType": "Use username and password or SSH public key for authentication to the VM", + "password": "Password for admin account of VMs", + "sshPublicKey": "SSH key for admin account of VMs" + }, + "constraints": { + "required": true, + "customPasswordRegex": "^((?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])|(?=.*[0-9])(?=.*[a-z])(?=.*[!@#$%^&*])|(?=.*[0-9])(?=.*[A-Z])(?=.*[!@#$%^&*])|(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*])).{12,72}$", + "customValidationMessage": "Password must be at least 12 characters long and have 3 out of the following: one number, one lower case, one upper case, or one special character" + }, + "options": { + "hideConfirmation": false, + "hidePassword": false + }, + "osPlatform": "Linux", + "visible": true + }, + { + "name": "wlsUserName", + "type": "Microsoft.Common.TextBox", + "label": "Username for WebLogic Administrator", + "defaultValue": "weblogic", + "toolTip": "Use only letters and numbers", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{1,30}$", + "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." + }, + "visible": true + }, + { + "name": "wlsPassword", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Password for WebLogic Administrator", + "confirmPassword": "Confirm password" + }, + "toolTip": "Password for WebLogic Administrator", + "constraints": { + "required": true, + "regex": "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)[A-Za-z\\d]{12,}$", + "validationMessage": "The password must contain at least 12 characters, with at least 1 uppercase letter, 1 lowercase letter and 1 number, and special characters are not allowed." + }, + "options": { + "hideConfirmation": false + }, + "visible": true + }, + { + "name": "dynamicClusterSize", + "type": "Microsoft.Common.TextBox", + "label": "Initial Dynamic Cluster Size", + "defaultValue": "3", + "toolTip": "Initial Number of Managed Servers that will be configured in the Dynamic Cluster", + "constraints": { + "required": true, + "regex": "^(2|3|4|5|6|7|8|9|10){1,2}$", + "validationMessage": "Initial Number of Managed Servers that will be configured in the Dynamic Cluster" + }, + "visible": true + }, + { + "name": "maxDynamicClusterSize", + "type": "Microsoft.Common.TextBox", + "label": "Maximum Dynamic Cluster Size", + "defaultValue": "8", + "toolTip": "Maximum Number of Managed Servers allowed to be configured in the Dynamic Cluster", + "constraints": { + "required": true, + "regex": "^(2|3|4|5|6|7|8|9|10){1,2}$", + "validationMessage": "Maximum Number of Managed Servers allowed to be configured in the Dynamic Cluster" + }, + "visible": true + } + ], + "visible": true + }, + { + "name": "basicsOptional", + "type": "Microsoft.Common.Section", + "label": "Optional Basic Configuration", + "elements": [ + { + "name": "basicsOptionalAcceptDefaults", + "type": "Microsoft.Common.OptionsGroup", + "label": "Accept defaults for optional configuration?", + "defaultValue": "Yes", + "toolTip": "Select 'No' to edit optional basic configuration.", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": "false" + }, + { + "label": "No", + "value": "true" + } + ], + "required": true + } + }, + { + "name": "managedServerPrefix", + "type": "Microsoft.Common.TextBox", + "label": "Managed Server Prefix", + "toolTip": "The string to prepend to the name of the managed server. Must start with letters and not have a run of more than eight digits.", + "defaultValue": "msp", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{3,20}$", + "validationMessage": "The prefix must be between 3 and 20 characters long and contain letters, numbers only." + }, + "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" + }, + { + "name": "wlsDomainName", + "type": "Microsoft.Common.TextBox", + "label": "WebLogic Domain Name", + "toolTip": "The name of the WebLogic Domain to create.", + "defaultValue": "clusterDomain", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{3,20}$", + "validationMessage": "The Domain Name must be between 3 and 20 characters long and contain letters, numbers only." + }, + "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" + }, + { + "name": "enableAdminHTTPListenPort", + "type": "Microsoft.Common.OptionsGroup", + "label": "Enable HTTP listen port on WebLogic Administration Server?", + "defaultValue": "Yes", + "toolTip": "Select 'No' to disable HTTP listen port on WebLogic Administration Server.", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": true + }, + { + "label": "No", + "value": false + } + ], + "required": true + }, + "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" + }, + { + "name": "useSystemAssignedManagedIdentity", + "label": "Cause a system assigned managed identity to be created for the VM(s).", + "type": "Microsoft.Common.OptionsGroup", + "toolTip": "System assigned managed identities enable credential-free secure access to many Azure resources from this VM.", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": true + }, + { + "label": "No", + "value": false + } + ], + "required": true + }, + "defaultValue": "Yes", + "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" + } + ], + "visible": true + }, + { + "name": "howToReportIssues", + "type": "Microsoft.Common.Section", + "label": "Report issues, get help, and share feedback", + "elements": [ + { + "name": "help", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "See the documentation for this offer.", + "link": { + "label": "Offer documentation", + "uri": "https://aka.ms/wls-vm-docs" + } + } + }, + { + "name": "howToReportIssueText", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "If you encounter problems during the deployment of Oracle WebLogic Server, report them here.", + "link": { + "label": "Issue tracker", + "uri": "https://aka.ms/arm-oraclelinux-wls-issues?version=${project.version}" + } + } + }, + { + "name": "howToJoinSlack", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "If you want to interact directly with the Oracle WebLogic community, join the public Slack channel named 'oracle-weblogic'.", + "link": { + "label": "Join Slack", + "uri": "https://aka.ms/arm-oraclelinux-wls-slack" + } + } + }, + { + "name": "survey", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "To get free help with Azure migration from the development team, fill out this survey.", + "link": { + "label": "Take survey", + "uri": "https://aka.ms/wls-on-azure-survey" + } + } + } + ], + "visible": true + } + ], + "steps": [ + { + "name": "section_sslConfiguration", + "type": "Microsoft.Common.Section", + "label": "TLS/SSL Configuration", + "elements": [ + { + "name": "sslConfigurationText", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "Selecting 'Yes' here will cause the template to provision WebLogic Administration Console on HTTPS (Secure) port, with your own TLS/SSL certificate.", + "link": { + "label": "Learn more", + "uri": "https://aka.ms/arm-oraclelinux-wls-ssl-config" + } + } + }, + { + "name": "enableCustomSSL", + "type": "Microsoft.Common.OptionsGroup", + "label": "Configure WebLogic Administration Console on HTTPS (Secure) port, with your own TLS/SSL certificate?", + "defaultValue": "No", + "toolTip": "Select 'Yes' to configure WebLogic Administration Console on HTTPS (Secure) port with your own TLS/SSL certificate.", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": true + }, + { + "label": "No", + "value": false + } + ], + "required": false + } + }, + { + "name": "uploadedCustomSSLSettings", + "type": "Microsoft.Common.Section", + "visible": "[steps('section_sslConfiguration').enableCustomSSL]", + "label": "TLS/SSL Configuration Settings", + "elements": [ + { + "name": "sslKeystoreInfo0", + "type": "Microsoft.Common.InfoBox", + "visible": "true", + "options": { + "icon": "Info", + "text": "You must provide different files for identity and trust KeyStores. Select here for more details.", + "uri": "https://aka.ms/arm-oraclelinux-wls-ssl-configuration" + } + }, + { + "name": "uploadedCustomIdentityKeyStoreData", + "type": "Microsoft.Common.FileUpload", + "label": "Identity KeyStore Data file(.jks,.p12)", + "toolTip": "Identity KeyStore for TLS/SSL configuration", + "constraints": { + "required": true, + "accept": ".jks,.p12" + }, + "options": { + "multiple": false, + "uploadMode": "file", + "openMode": "binary" + }, + "visible": true + }, + { + "name": "uploadedCustomIdentityKeyStorePassphrase", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Password", + "confirmPassword": "Confirm password" + }, + "toolTip": " The passphrase for the Identity KeyStore", + "constraints": { + "required": true, + "regex": "^.{6,}$", + "validationMessage": "Keypass must be at least 6 characters long." + }, + "options": { + "hideConfirmation": false + }, + "visible": true + }, + { + "name": "uploadedCustomIdentityKeyStoreType", + "type": "Microsoft.Common.DropDown", + "visible": "true", + "label": "The Identity KeyStore type (JKS,PKCS12)", + "defaultValue": "JKS", + "toolTip": "One of the supported KeyStore types", + "constraints": { + "allowedValues": [ + { + "label": "JKS", + "value": "JKS" + }, + { + "label": "PKCS12", + "value": "PKCS12" + } + ], + "required": true + } + }, + { + "name": "uploadedPrivateKeyAlias", + "type": "Microsoft.Common.TextBox", + "visible": "true", + "label": "The alias of the server's private key within the Identity KeyStore", + "defaultValue": "", + "toolTip": "Use only letters and numbers", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{1,30}$", + "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." + } + }, + { + "name": "uploadedPrivateKeyPassPhrase", + "type": "Microsoft.Common.PasswordBox", + "visible": "true", + "label": { + "password": "The passphrase for the server's private key within the Identity KeyStore", + "confirmPassword": "Confirm passphrase" + }, + "toolTip": "Use only letters and numbers", + "constraints": { + "required": true, + "regex": "^.{6,}$", + "validationMessage": "Keypass must be at least 6 characters long." + }, + "options": { + "hideConfirmation": false + } + }, + { + "name": "uploadedCustomTrustKeyStoreData", + "type": "Microsoft.Common.FileUpload", + "label": "Trust KeyStore Data file(.jks,.p12)", + "toolTip": "Trust KeyStore for TLS/SSL configuration.", + "constraints": { + "required": true, + "accept": ".jks,.p12" + }, + "options": { + "multiple": false, + "uploadMode": "file", + "openMode": "binary" + }, + "visible": true + }, + { + "name": "uploadedCustomTrustKeyStorePassPhrase", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Password", + "confirmPassword": "Confirm password" + }, + "toolTip": " The passphrase for the Trust KeyStore", + "constraints": { + "required": true, + "regex": "^.{6,}$", + "validationMessage": "Keypass must be at least 6 characters long." + }, + "options": { + "hideConfirmation": false + }, + "visible": true + }, + { + "name": "uploadedCustomTrustKeyStoreType", + "type": "Microsoft.Common.DropDown", + "visible": "true", + "label": "The Trust KeyStore type (JKS,PKCS12)", + "defaultValue": "JKS", + "toolTip": "One of the supported KeyStore types", + "constraints": { + "allowedValues": [ + { + "label": "JKS", + "value": "JKS" + }, + { + "label": "PKCS12", + "value": "PKCS12" + } + ], + "required": true + } + } + ] + } + ] + }, + { + "name": "section_ohs", + "type": "Microsoft.Common.Section", + "label": "Oracle HTTP Server Load Balancer", + "elements": [ + { + "name": "connectToOHSext", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "Selecting 'Yes' here will cause the template to provision an Azure Oracle HTTP Server, set up a public IP, and configuration with WebLogic cluster address. Further configuration may be necessary after deployment.", + "link": { + "label": "Learn more", + "uri": "https://docs.oracle.com/en/middleware/fusion-middleware/web-tier/12.2.1.4/index.html" + } + } + }, + { + "name": "enableOHS", + "type": "Microsoft.Common.OptionsGroup", + "label": "Connect to Oracle HTTP Server?", + "defaultValue": "No", + "toolTip": "Select 'Yes' to cause an Azure Oracle HTTP Server to be created as the load balancer for the cluster.", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": true + }, + { + "label": "No", + "value": false + } + ], + "required": false + } + }, + { + "name": "sslText", + "type": "Microsoft.Common.TextBlock", + "visible": "[steps('section_ohs').enableOHS]", + "options": { + "text": "Oracle HTTP Server integration requires a TLS/SSL certificate to enable TLS/SSL termination. End-to-end TLS/SSL encryption is not supported by the template.", + "link": { + "label": "Learn more", + "uri": "https://aka.ms/arm-oraclelinux-wls-dynamic-cluster-ohs" + } + } + }, + { + "name": "ohsSkuUrnVersion", + "type": "Microsoft.Common.DropDown", + "label": "Oracle HTTP Server image", + "defaultValue": "OHS 12.2.1.4.0 and JDK8 on Oracle Linux 7.6", + "toolTip": "Choose Oracle HTTP Server image, which is provided by Oracle, with Java and HTTP Server preinstalled.", + "constraints": { + "allowedValues": [ + { + "label": "OHS 12.2.1.4.0 and JDK8 on Oracle Linux 7.3", + "value": "ohs-122140-jdk8-ol73;ohs-122140-jdk8-ol73;latest" + }, + { + "label": "OHS 12.2.1.4.0 and JDK8 on Oracle Linux 7.4", + "value": "ohs-122140-jdk8-ol74;ohs-122140-jdk8-ol74;latest" + }, + { + "label": "OHS 12.2.1.4.0 and JDK8 on Oracle Linux 7.6", + "value": "ohs-122140-jdk8-ol76;ohs-122140-jdk8-ol76;latest" + } + ] + }, + "visible": "[steps('section_ohs').enableOHS]" + }, + { + "name": "ohsDomainName", + "type": "Microsoft.Common.TextBox", + "label": "Oracle HTTP Server Domain name", + "defaultValue": "ohsStandaloneDomain", + "toolTip": "Oracle HTTP Server Domain Name", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1}){1,2}$", + "validationMessage": "[if(greater(length(steps('section_ohs').ohsDomainName), 90),'Must be less than 90 characters.', 'Value only allows alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" + }, + "visible": "[steps('section_ohs').enableOHS]" + }, + { + "name": "ohsComponentName", + "type": "Microsoft.Common.TextBox", + "label": "Oracle HTTP Server Component name", + "defaultValue": "ohs_component", + "toolTip": "Oracle HTTP Server Component name", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1}){1,2}$", + "validationMessage": "[if(greater(length(steps('section_ohs').ohsDomainName), 90),'Must be less than 90 characters.', 'Value only allows alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" + }, + "visible": "[steps('section_ohs').enableOHS]" + }, + { + "name": "ohsNMUser", + "type": "Microsoft.Common.TextBox", + "label": "Oracle HTTP Server NodeManager username", + "defaultValue": "", + "toolTip": "Oracle HTTP Server NodeManager username", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1}){1,2}$", + "validationMessage": "[if(greater(length(steps('section_ohs').ohsDomainName), 90),'Must be less than 90 characters.', 'Value only allows alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" + }, + "visible": "[steps('section_ohs').enableOHS]" + }, + { + "name": "ohsNMPassword", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Oracle HTTP Server NodeManager Password", + "confirmPassword": "Confirm password" + }, + "toolTip": "Oracle HTTP Server NodeManager password", + "constraints": { + "required": true, + "regex": "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)[A-Za-z\\d]{12,}$", + "validationMessage": "The password must contain at least 12 characters, with at least 1 uppercase letter, 1 lowercase letter and 1 number, and special characters are not allowed." + }, + "options": { + "hideConfirmation": false + }, + "visible": "[steps('section_ohs').enableOHS]" + }, + { + "name": "ohshttpPort", + "type": "Microsoft.Common.TextBox", + "label": "Oracle HTTP Server HTTP port", + "defaultValue": "7777", + "toolTip": "Oracle HTTP Server HTTP port", + "constraints": { + "required": true, + "regex": "^[0-9]{2,5}$", + "validationMessage": "[if(greater(length(steps('section_ohs').ohshttpPort), 90),'Resource group names only allow up to 90 characters.', 'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" + }, + "visible": "[steps('section_ohs').enableOHS]" + }, + { + "name": "ohshttpsPort", + "type": "Microsoft.Common.TextBox", + "label": "Oracle HTTP Server HTTPS port", + "defaultValue": "4444", + "toolTip": "Oracle HTTP Server HTTPS port", + "constraints": { + "required": true, + "regex": "^[0-9]{2,5}$", + "validationMessage": "[if(greater(length(steps('section_ohs').ohshttpsPort), 90),'Resource group names only allow up to 90 characters.', 'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" + }, + "visible": "[steps('section_ohs').enableOHS]" + }, + { + "name": "oracleVaultPswd", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Oracle Vault Password", + "confirmPassword": "Confirm password" + }, + "toolTip": "The password to configure SSL store Oracle Vault", + "constraints": { + "required": true, + "regex": "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)[A-Za-z\\d]{12,}$", + "validationMessage": "The password must contain at least 12 characters, with at least 1 uppercase letter, 1 lowercase letter and 1 number, and special characters are not allowed." + }, + "options": { + "hideConfirmation": false + }, + "visible": "[steps('section_ohs').enableOHS]" + }, + { + "name": "uploadedCustomSSLSettings", + "type": "Microsoft.Common.Section", + "visible": "[steps('section_ohs').enableOHS]", + "label": "TLS/SSL Configuration Settings", + "elements": [ + { + "name": "uploadedKeyStoreData", + "type": "Microsoft.Common.FileUpload", + "label": "TLS/SSL certificate Data file(.jks,.p12)", + "toolTip": "KeyStore for TLS/SSL configuration", + "constraints": { + "required": true, + "accept": ".jks,.p12" + }, + "options": { + "multiple": false, + "uploadMode": "file", + "openMode": "binary" + }, + "visible": true + }, + { + "name": "uploadedKeyStorePassword", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Password", + "confirmPassword": "Confirm password" + }, + "toolTip": " The password for the TLS/SSL certificate Data", + "constraints": { + "required": true, + "regex": "^.{6,}$", + "validationMessage": "Keypass must be at least 6 characters long." + }, + "options": { + "hideConfirmation": false + }, + "visible": true + }, + { + "name": "uploadedKeyStoreType", + "type": "Microsoft.Common.DropDown", + "visible": "true", + "label": "Type of the certificate format(JKS,PKCS12)", + "defaultValue": "JKS", + "toolTip": "One of the supported KeyStore types", + "constraints": { + "allowedValues": [ + { + "label": "JKS", + "value": "JKS" + }, + { + "label": "PKCS12", + "value": "PKCS12" + } + ], + "required": true + } + } + ] + } + ], + "visible": true + }, + { + "name": "section_networkingConfiguration", + "type": "Microsoft.Common.Section", + "label": "Networking", + "elements": [ + { + "name": "denyPublicTrafficForAdminServer", + "type": "Microsoft.Common.OptionsGroup", + "label": "Deny public traffic for admin server?", + "visible": "[equals(steps('section_networkingConfiguration').virtualNetwork.newOrExisting, 'new')]", + "defaultValue": "No", + "toolTip": "Select 'Yes' to deny public traffic for admin server. Configuration here for port 7001 and 7002 has a higher priority than above.", + "constraints": { + "allowedValues": [ + { + "label": "No", + "value": false + }, + { + "label": "Yes", + "value": true + } + ], + "required": true + } + }, + { + "name": "denyPublicTrafficForManagedServer", + "type": "Microsoft.Common.OptionsGroup", + "visible": "[and(steps('section_ohs').enableOHS, equals(steps('section_networkingConfiguration').virtualNetwork.newOrExisting, 'new'))]", + "label": "Deny public traffic for managed server?", + "defaultValue": "Yes", + "toolTip": "Select 'Yes' to deny public traffic for managed server. Configuration here for port 8002 ~ 8001 + 'node number' has a higher priority than the 'Ports and port ranges to expose' in basic blade.", + "constraints": { + "allowedValues": [ + { + "label": "No", + "value": false + }, + { + "label": "Yes", + "value": true + } + ], + "required": true + } + }, + { + "name": "vnetInfo", + "type": "Microsoft.Common.InfoBox", + "options": { + "icon": "Info", + "text": "When creating a new virtual network, the subnet's address prefix is calculated automatically based on the virtual
    network's address prefix. When using an existing virtual network, a minimum virtual network size of /28 and a
    minimum subnet size of /29 are required. Additionally, the subnet must have adequate available addresses for the
    server setup. Oracle HTTP Server will be created in this subnet if enabled." + } + }, + { + "name": "virtualNetwork", + "type": "Microsoft.Network.VirtualNetworkCombo", + "label": { + "virtualNetwork": "Virtual network", + "subnets": "Subnets" + }, + "toolTip": { + "virtualNetwork": "Name of the virtual network", + "subnets": "Subnets for the virtual network" + }, + "defaultValue": { + "name": "[concat('wlsdcluster-vnet-',take(guid(), 8))]", + "addressPrefixSize": "/28" + }, + "constraints": { + "minAddressPrefixSize": "/28" + }, + "subnets": { + "subnet1": { + "label": "Subnet for WebLogic (OHS will be also created in this subnet if enabled)", + "defaultValue": { + "name": "wls-subnet", + "addressPrefixSize": "/28" + }, + "constraints": { + "minAddressPrefixSize": "/29", + "minAddressCount": "[if(bool(steps('section_ohs').enableOHS), add(int(basics('basicsRequired').maxDynamicClusterSize), 2), add(int(basics('basicsRequired').maxDynamicClusterSize), 1))]", + "requireContiguousAddresses": false + } + } + } + }, + { + "name": "dnsConfigurationText", + "type": "Microsoft.Common.TextBlock", + "visible": "[equals(steps('section_networkingConfiguration').virtualNetwork.newOrExisting, 'new')]", + "options": { + "text": "Selecting 'Yes' here will cause the template to provision Load Balancer and Oracle WebLogic Administration Console using custom DNS Name (example: console.contoso.com)", + "link": { + "label": "Learn more", + "uri": "https://aka.ms/arm-oraclelinux-wls-dns" + } + } + }, + { + "name": "enableCustomDNS", + "type": "Microsoft.Common.OptionsGroup", + "visible": "[equals(steps('section_networkingConfiguration').virtualNetwork.newOrExisting, 'new')]", + "label": "Configure Custom DNS Alias?", + "defaultValue": "No", + "toolTip": "Select 'Yes' to configure Custom DNS Alias.", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": true + }, + { + "label": "No", + "value": false + } + ], + "required": false + } + }, + { + "name": "dnsLabelPrefix", + "type": "Microsoft.Common.TextBox", + "label": "DNS Label Prefix", + "toolTip": "The string to prepend to the DNS label.", + "defaultValue": "wls", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{3,10}$", + "validationMessage": "The prefix must be between 3 and 10 characters long and contain letters, numbers only." + }, + "visible": "[bool(steps('section_networkingConfiguration').enableCustomDNS)]" + }, + { + "name": "portsToExpose", + "label": "Ports and port ranges to expose (N or N-N, comma separated)", + "type": "Microsoft.Common.TextBox", + "toolTip": "Ports and port ranges to expose (N or N-N, comma separated)", + "defaultValue": "80,443,7001-9000", + "constraints": { + "required": true, + "regex": "^(((([0-9]+-[0-9]+)|([0-9]+))[,]?)+[^,]){1,1000}$", + "validationMessage": "Only numbers, hyphen separated ranges of numbers, separated by commas" + }, + "visible": "[bool(steps('section_networkingConfiguration').enableCustomDNS)]" + }, + { + "name": "customDNSSettings", + "type": "Microsoft.Common.Section", + "label": "DNS Configuration Settings", + "visible": "[bool(steps('section_networkingConfiguration').enableCustomDNS)]", + "elements": [ + { + "name": "bringDNSZone", + "type": "Microsoft.Common.OptionsGroup", + "label": "Use an existing Azure DNS Zone", + "defaultValue": "No", + "toolTip": "Select 'Yes' to configure Custom DNS Alias based on an existing Azure DNS Zone. Select 'No' to create an Azure DNS Zone and Custom DNS Alias.", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": true + }, + { + "label": "No", + "value": false + } + ] + } + }, + { + "name": "createDNSZoneText", + "type": "Microsoft.Common.InfoBox", + "visible": "[not(bool(steps('section_networkingConfiguration').customDNSSettings.bringDNSZone))]", + "options": { + "icon": "Info", + "text": "You must perform DNS Domain Delegation at your DNS Registry after deployment.", + "uri": "https://aka.ms/dns-domain-delegation" + } + }, + { + "name": "createDNSZonePublicResolveWarning", + "type": "Microsoft.Common.InfoBox", + "visible": "[bool(steps('section_networkingConfiguration').customDNSSettings.bringDNSZone)]", + "options": { + "icon": "Info", + "text": "The referenced hostnames must be publicly resolvable before deployment.", + "uri": "https://learn.microsoft.com/en-us/azure/dns/dns-getstarted-portal" + } + }, + { + "name": "infoDNSIndentity", + "type": "Microsoft.Common.InfoBox", + "visible": "[bool(steps('section_networkingConfiguration').customDNSSettings.bringDNSZone)]", + "options": { + "icon": "Info", + "text": "This option will add/update records in your Azure DNS Zone. The Azure identity deploying this feature must have one of the following two sets of Azure role-based access control roles:
  • Contributor and User Access Administrator of the current subscription.
  • Owner of the current subscription.
  • " + } + }, + { + "name": "dnszoneName", + "type": "Microsoft.Common.TextBox", + "label": "DNS Zone Name", + "defaultValue": "", + "toolTip": "Use only letters and numbers and periods to separate Domains", + "constraints": { + "required": true, + "regex": "^([0-9a-zA-Z_-]{1,63}\\.){1,33}[0-9a-zA-Z_-]{1,63}$", + "validationMessage": "There must be between 2 and 34 labels. For example, \"contoso.com\" has 2 labels. Each label must contain between 1 and 63 characters. Each label must only contain letters, numbers, underscores, and dashes." + } + }, + { + "name": "dnsZoneResourceGroup", + "type": "Microsoft.Common.TextBox", + "label": "Name of the resource group contains the DNS Zone in current subscription", + "defaultValue": "", + "toolTip": "Name of the resource group contains the DNS Zone in current subscription", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z.\\-_()]{0,89}([a-z0-9A-Z\\-_()]{1})$", + "validationMessage": "[if(greater(length(steps('section_networkingConfiguration').existingDNSZonesSettings.dnsZoneResourceGroup), 90),'Resource group names only allow up to 90 characters.', 'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.')]" + }, + "visible": "[steps('section_networkingConfiguration').customDNSSettings.bringDNSZone]" + }, + { + "name": "dnszoneAdminConsoleLabel", + "type": "Microsoft.Common.TextBox", + "label": "Label for Oracle WebLogic Administration Console", + "defaultValue": "admin", + "toolTip": "Specify a label to generate subdomain of Oracle WebLogic Administration Console", + "constraints": { + "required": true, + "validations": [ + { + "regex": "^([0-9a-zA-Z_-]{1,63}\\.){0,33}[0-9a-zA-Z_-]{1,63}$", + "message": "Each label must contain between 1 and 63 characters. Each label must only contain letters, numbers, underscores, and dashes." + }, + { + "isValid": "[less(sub(length(concat(steps('section_networkingConfiguration').customDNSSettings.dnszoneAdminConsoleLabel,'.',steps('section_networkingConfiguration').customDNSSettings.dnszoneName)),length(replace(concat(steps('section_networkingConfiguration').customDNSSettings.dnszoneAdminConsoleLabel,'.',steps('section_networkingConfiguration').customDNSSettings.dnszoneName), '.', ''))),34)]", + "message": "Subdomain must be between 2 and 34 labels. For example, \"admin.contoso.com\" has 3 labels." + } + ] + } + }, + { + "name": "dnszoneLoadBalancerLabel", + "type": "Microsoft.Common.TextBox", + "label": "Label for Load Balancer", + "defaultValue": "www", + "toolTip": "Specify a label to generate subdomain of Load Balancer", + "constraints": { + "required": true, + "validations": [ + { + "regex": "^([0-9a-zA-Z_-]{1,63}\\.){0,33}[0-9a-zA-Z_-]{1,63}$", + "message": "Each label must contain between 1 and 63 characters. Each label must only contain letters, numbers, underscores, and dashes." + }, + { + "isValid": "[less(sub(length(concat(if(empty(steps('section_networkingConfiguration').customDNSSettings.dnszoneLoadBalancerLabel), '', steps('section_networkingConfiguration').customDNSSettings.dnszoneLoadBalancerLabel),'.',steps('section_networkingConfiguration').customDNSSettings.dnszoneName)),length(replace(concat(if(empty(steps('section_networkingConfiguration').customDNSSettings.dnszoneLoadBalancerLabel), '', steps('section_networkingConfiguration').customDNSSettings.dnszoneLoadBalancerLabel),'.',steps('section_networkingConfiguration').customDNSSettings.dnszoneName), '.', ''))),34)]", + "message": "Subdomain must be between 2 and 34 labels. For example, \"applications.contoso.com\" has 3 labels." + } + ] + }, + "visible": "[and(bool(steps('section_ohs').enableOHS), bool(steps('section_networkingConfiguration').enableCustomDNS))]" + } + ] + } + ] + }, + { + "name": "section_database", + "type": "Microsoft.Common.Section", + "label": "Database", + "subLabel": { + "preValidation": "Configure integrations to Azure services", + "postValidation": "Done" + }, + "bladeTitle": "Service Integrations", + "elements": [ + { + "name": "aboutDatabase", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "Selecting 'Yes' here and providing the configuration will cause the template to configure the WebLogic Server to connect to the desired pre-existing database. The database must be network accessible to the VNET and subnets created by the template." + } + }, + { + "name": "enableDB", + "type": "Microsoft.Common.OptionsGroup", + "label": "Connect to database?", + "defaultValue": "No", + "toolTip": "Select 'Yes' and provide required info to configure the connection to a database.", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": "true" + }, + { + "label": "No", + "value": "false" + } + ], + "required": true + } + }, + { + "name": "databaseConnectionInfo", + "type": "Microsoft.Common.Section", + "label": "Connection settings", + "elements": [ + { + "name": "databaseType", + "type": "Microsoft.Common.DropDown", + "label": "Choose database type", + "toolTip": "Choose database type", + "defaultValue": "Oracle database", + "constraints": { + "allowedValues": [ + { + "label": "PostgreSQL (Supports passwordless connection)", + "value": "postgresql" + }, + { + "label": "Oracle database", + "value": "oracle" + }, + { + "label": "Microsoft SQL Server (Supports passwordless connection)", + "value": "sqlserver" + }, + { + "label": "MySQL (Supports passwordless connection)", + "value": "mysql" + } + ], + "required": true + }, + "visible": true + }, + { + "name": "mysqlJDBCDriverInfo", + "type": "Microsoft.Common.InfoBox", + "visible": "[and(bool(steps('section_database').enableDB),equals(steps('section_database').databaseConnectionInfo.databaseType, 'mysql'))]", + "options": { + "icon": "Info", + "text": "To support passwordless connection and various functionalities, the offer will upgrade the
    Oracle WebLogic Server MySQL driver with recent MySQL Connector Java driver." + } + }, + { + "name": "jdbcDataSourceName", + "type": "Microsoft.Common.TextBox", + "label": "JNDI Name", + "toolTip": "The JNDI name for the database JDBC connection", + "defaultValue": "", + "constraints": { + "required": true, + "validations": [ + { + "regex": "^[a-z0-9A-Z/]{1,30}$", + "message": "The value must be 1-30 characters long and must only contain letters, numbers, and slashes (/)." + } + ] + }, + "visible": true + }, + { + "name": "dsConnectionURL", + "type": "Microsoft.Common.TextBox", + "label": "DataSource Connection String", + "toolTip": "The JDBC connection string for the database", + "defaultValue": "", + "constraints": { + "required": true, + "validations": [ + { + "regex": "^jdbc:.*$", + "message": "A valid JDBC URL must start with 'jdbc:'." + }, + { + "isValid": "[startsWith(steps('section_database').databaseConnectionInfo.dsConnectionURL, concat('jdbc:', steps('section_database').databaseConnectionInfo.databaseType))]", + "message": "A valid JDBC URL for the chosen database type must be provided." + }, + { + "isValid": "[if(and(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection), equals(steps('section_database').databaseConnectionInfo.databaseType, 'mysql')), and(not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'defaultAuthenticationPlugin')),not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'authenticationPlugins')), not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'azure.clientId'))), 'true')]", + "message": "The offer will append defaultAuthenticationPlugin, authenticationPlugins with Azure provided plugins, and append azure.clientId with your managed identity client ID automatically, please do not specify them in your connection string." + }, + { + "isValid": "[if(and(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection), equals(steps('section_database').databaseConnectionInfo.databaseType, 'postgresql')), and(not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'authenticationPluginClassName')),not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'azure.clientId'))), 'true')]", + "message": "The offer will append authenticationPluginClassName with Azure provided plugins, and append azure.clientId with your managed identity client ID automatically, please do not specify them in your connection string." + }, + { + "isValid": "[if(and(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection), equals(steps('section_database').databaseConnectionInfo.databaseType, 'sqlserver')), and(not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'authentication=ActiveDirectoryMSI')),not(contains(steps('section_database').databaseConnectionInfo.dsConnectionURL, 'msiClientId'))), 'true')]", + "message": "The offer will append authentication with ActiveDirectoryMSI, and append msiClientId with your managed identity client ID automatically, please do not specify them in your connection string." + }, + { + "isValid": "[if(and(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection0),equals(steps('section_database').databaseConnectionInfo.databaseType, 'sqlserver')), greater(length(steps('section_database').databaseConnectionInfo.dbIdentity.userAssignedIdentities),0), bool('true'))]", + "message": "You must select at least one managed identity that has access to your database." + } + ] + }, + "visible": true + }, + { + "name": "dbGlobalTranPro", + "type": "Microsoft.Common.DropDown", + "label": "Global transactions protocol", + "defaultValue": "OnePhaseCommit", + "multiLine": true, + "toolTip": "Determines the transaction protocol (global transaction processing behavior) for the data source.", + "constraints": { + "allowedValues": [ + { + "label": "TwoPhaseCommit", + "description": "Standard XA transaction processing. Requires an XA driver.", + "value": "TwoPhaseCommit" + }, + { + "label": "LoggingLastResource", + "description": "A performance enhancement for one non-XA resource.", + "value": "LoggingLastResource" + }, + { + "label": "EmulateTwoPhaseCommit", + "description": "Enables one non-XA resource to participate in a global transaction, but has some risk to data.", + "value": "EmulateTwoPhaseCommit" + }, + { + "label": "OnePhaseCommit", + "description": "One-phase XA transaction processing using a non-XA driver. This is the default setting.", + "value": "OnePhaseCommit" + }, + { + "label": "None", + "description": "Support for local transactions only.", + "value": "None" + } + ], + "required": true + }, + "visible": true + }, + { + "name": "enablePswlessConnection0", + "type": "Microsoft.Common.CheckBox", + "label": "Use passwordless datasource connection", + "toolTip": "Use passwordless datasource connection.", + "visible": "[and(bool(steps('section_database').enableDB),equals(steps('section_database').databaseConnectionInfo.databaseType, 'sqlserver'))]" + }, + { + "name": "dbUser", + "type": "Microsoft.Common.TextBox", + "label": "Database username", + "toolTip": "Use only letters and numbers", + "defaultValue": "", + "constraints": { + "required": true, + "validations": [ + { + "regex": "^(?!\\-)([a-z0-9A-Z@\\-]{1,128})([^\\-])$", + "message": "The value must be 1-128 characters long and must only contain letters, numbers, hyphen(-) and the at sign, no hyphen allowed at the beginning and the end of database username." + }, + { + "isValid": "[if(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection), greater(length(steps('section_database').databaseConnectionInfo.dbIdentity.userAssignedIdentities),0), bool('true'))]", + "message": "You must select at least one managed identity that has access to your database." + } + ] + }, + "visible": "[and(bool(steps('section_database').enableDB), not(and(steps('section_database').databaseConnectionInfo.enablePswlessConnection0, equals(steps('section_database').databaseConnectionInfo.databaseType, 'sqlserver'))))]" + }, + { + "name": "enablePswlessConnection", + "type": "Microsoft.Common.CheckBox", + "label": "Use passwordless datasource connection", + "toolTip": "Use passwordless datasource connection.", + "visible": "[and(bool(steps('section_database').enableDB),or(equals(steps('section_database').databaseConnectionInfo.databaseType, 'mysql'),equals(steps('section_database').databaseConnectionInfo.databaseType, 'postgresql')))]" + }, + { + "name": "dbPassword", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Database Password", + "confirmPassword": "Confirm password" + }, + "toolTip": "Database Password", + "constraints": { + "required": true, + "regex": "^((?=.*[0-9])(?=.*[a-zA-Z!@#$%^&*])).{5,128}$", + "validationMessage": "The password must be between 5 and 128 characters long and have at least one number." + }, + "options": { + "hideConfirmation": false + }, + "visible": "[and(bool(steps('section_database').enableDB), not(or(steps('section_database').databaseConnectionInfo.enablePswlessConnection, steps('section_database').databaseConnectionInfo.enablePswlessConnection0)))]" + }, + { + "name": "dbIdentity", + "type": "Microsoft.ManagedIdentity.IdentitySelector", + "label": "Connect database with Managed Identity", + "toolTip": { + "userAssignedIdentity": "Select a user assigned identity that has access to your database. For how to create a database user for your managed identity, see https://aka.ms/javaee-db-identity." + }, + "defaultValue": { + "systemAssignedIdentity": "Off" + }, + "options": { + "hideSystemAssignedIdentity": true, + "hideUserAssignedIdentity": false + }, + "visible": "[and(bool(steps('section_database').enableDB), or(steps('section_database').databaseConnectionInfo.enablePswlessConnection, steps('section_database').databaseConnectionInfo.enablePswlessConnection0))]" + } + ], + "visible": "[bool(steps('section_database').enableDB)]" + } + ] + }, + { + "name": "section_coherence", + "label": "Coherence", + "subLabel": { + "preValidation": "Configure Coherence.", + "postValidation": "Done" + }, + "bladeTitle": "Coherence", + "elements": [ + { + "name": "aboutCoherence", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "Selecting 'Yes' here and providing the configuration will cause the template to create a Coherence cluster, the WebLogic Domain will create a data tier configured with Managed Coherence cache servers.", + "link": { + "label": "Learn more", + "uri": "https://aka.ms/arm-oraclelinux-wls-coherence" + } + } + }, + { + "name": "enableCoherence", + "type": "Microsoft.Common.OptionsGroup", + "label": "Use Coherence cache?", + "defaultValue": "No", + "toolTip": "Select 'Yes' and provide required info to configure Coherence cluster.", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": "true" + }, + { + "label": "No", + "value": "false" + } + ], + "required": true + } + }, + { + "name": "coherenceInfo", + "type": "Microsoft.Common.Section", + "label": "Coherence settings", + "elements": [ + { + "name": "coherenceVMSizeSelect", + "type": "Microsoft.Compute.SizeSelector", + "label": "Coherence virtual machine size", + "toolTip": "The size of virtual machine for Coherence cache servers.", + "recommendedSizes": [ + "[basics('vmSizeSelect')]" + ], + "constraints": { + "excludedSizes": [ + "Standard_B1ls", + "Standard_A0", + "Basic_A0", + "Standard_B1s" + ] + }, + "osPlatform": "Linux", + "count": "1", + "visible": true + }, + { + "name": "numberOfCoherenceStorageInstances", + "type": "Microsoft.Common.TextBox", + "label": "Number of Coherence cache servers", + "toolTip": "Number of Coherence cache instances, used to create virtual machines and WebLogic Managed Server.", + "defaultValue": "1", + "constraints": { + "required": true, + "regex": "^[0-9]+$", + "validationMessage": "The value must be a valid number." + } + }, + { + "name": "enableCoherenceWebLocalStorage", + "type": "Microsoft.Common.OptionsGroup", + "label": "Coherence Web Local Storage Enabled", + "defaultValue": "Yes", + "toolTip": "Specifies whether Local Storage is enabled for the Coherence*Web cluster tier", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": "true" + }, + { + "label": "No", + "value": "false" + } + ], + "required": true + } + } + ], + "visible": "[bool(steps('section_coherence').enableCoherence)]" + } + ] + } + ], + "outputs": { + "Location": "[location()]", + "adminPasswordOrKey": "[if(equals(basics('basicsRequired').adminPasswordOrKey.authenticationType, 'password'), basics('basicsRequired').adminPasswordOrKey.password, basics('basicsRequired').adminPasswordOrKey.sshPublicKey)]", + "adminUsername": "[basics('basicsRequired').adminUsername]", + "addressPrefixes": "[steps('section_networkingConfiguration').virtualNetwork.addressPrefixes]", + "authenticationType": "[basics('basicsRequired').adminPasswordOrKey.authenticationType]", + "databaseType": "[steps('section_database').databaseConnectionInfo.databaseType]", + "denyPublicTrafficForAdminServer": "[steps('section_networkingConfiguration').denyPublicTrafficForAdminServer]", + "denyPublicTrafficForManagedServer": "[steps('section_networkingConfiguration').denyPublicTrafficForManagedServer]", + "dbIdentity": "[steps('section_database').databaseConnectionInfo.dbIdentity]", + "dnsLabelPrefix": "[steps('section_networkingConfiguration').dnsLabelPrefix]", + "dsConnectionURL": "[steps('section_database').databaseConnectionInfo.dsConnectionURL]", + "dnszoneName": "[steps('section_networkingConfiguration').customDNSSettings.dnszoneName]", + "dnszoneResourceGroup": "[steps('section_networkingConfiguration').customDNSSettings.dnsZoneResourceGroup]", + "dnszoneAdminConsoleLabel": "[steps('section_networkingConfiguration').customDNSSettings.dnszoneAdminConsoleLabel]", + "dnszoneLoadBalancerLabel": "[steps('section_networkingConfiguration').customDNSSettings.dnszoneLoadBalancerLabel]", + "dbGlobalTranPro": "[steps('section_database').databaseConnectionInfo.dbGlobalTranPro]", + "dbPassword": "[steps('section_database').databaseConnectionInfo.dbPassword]", + "dbUser": "[steps('section_database').databaseConnectionInfo.dbUser]", + "dynamicClusterSize": "[int(basics('basicsRequired').dynamicClusterSize)]", + "enableCoherence": "[bool(steps('section_coherence').enableCoherence)]", + "enableCoherenceWebLocalStorage": "[bool(if(bool(steps('section_coherence').enableCoherence),steps('section_coherence').coherenceInfo.enableCoherenceWebLocalStorage,'false'))]", + "enableDB": "[bool(steps('section_database').enableDB)]", + "enableCustomDNS": "[bool(steps('section_networkingConfiguration').enableCustomDNS)]", + "enableCustomSSL": "[bool(steps('section_sslConfiguration').enableCustomSSL)]", + "enableOHS": "[bool(steps('section_ohs').enableOHS)]", + "enablePswlessConnection": "[or(bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection), bool(steps('section_database').databaseConnectionInfo.enablePswlessConnection0))]", + "hasDNSZones": "[bool(if(bool(steps('section_networkingConfiguration').enableCustomDNS), steps('section_networkingConfiguration').customDNSSettings.bringDNSZone, 'false'))]", + "jdbcDataSourceName": "[steps('section_database').databaseConnectionInfo.jdbcDataSourceName]", + "managedServerPrefix": "[basics('basicsOptional').managedServerPrefix]", + "maxDynamicClusterSize": "[int(basics('basicsRequired').maxDynamicClusterSize)]", + "numberOfCoherenceCacheInstances": "[int(if(bool(steps('section_coherence').enableCoherence),steps('section_coherence').coherenceInfo.numberOfCoherenceStorageInstances,'1'))]", + "portsToExpose": "[steps('section_networkingConfiguration').portsToExpose]", + "skuUrnVersion": "[basics('skuUrnVersion')]", + "useSystemAssignedManagedIdentity": "[basics('basicsOptional').useSystemAssignedManagedIdentity]", + "vmSize": "[basics('vmSizeSelect')]", + "vmSizeSelectForCoherence": "[steps('section_coherence').coherenceInfo.coherenceVMSizeSelect]", + "wlsDomainName": "[basics('basicsOptional').wlsDomainName]", + "wlsPassword": "[basics('basicsRequired').wlsPassword]", + "wlsUserName": "[basics('basicsRequired').wlsUserName]", + "ohsSkuUrnVersion": "[steps('section_ohs').ohsSkuUrnVersion]", + "ohsDomainName": "[steps('section_ohs').ohsDomainName]", + "ohsComponentName": "[steps('section_ohs').ohsComponentName]", + "ohsNMUser": "[steps('section_ohs').ohsNMUser]", + "ohsNMPassword": "[steps('section_ohs').ohsNMPassword]", + "ohshttpPort": "[steps('section_ohs').ohshttpPort]", + "ohshttpsPort": "[steps('section_ohs').ohshttpsPort]", + "oracleVaultPswd": "[steps('section_ohs').oracleVaultPswd]", + "enableHTTPAdminListenPort": "[basics('basicsOptional').enableAdminHTTPListenPort]", + "subnetName": "[steps('section_networkingConfiguration').virtualNetwork.subnets.subnet1.name]", + "subnetPrefix": "[steps('section_networkingConfiguration').virtualNetwork.subnets.subnet1.addressPrefix]", + "uploadedCustomIdentityKeyStoreData": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomIdentityKeyStoreData]", + "uploadedCustomIdentityKeyStorePassphrase": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomIdentityKeyStorePassphrase]", + "uploadedCustomIdentityKeyStoreType": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomIdentityKeyStoreType]", + "uploadedCustomTrustKeyStoreData": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomTrustKeyStoreData]", + "uploadedCustomTrustKeyStorePassPhrase": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomTrustKeyStorePassPhrase]", + "uploadedCustomTrustKeyStoreType": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedCustomTrustKeyStoreType]", + "uploadedPrivateKeyAlias": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedPrivateKeyAlias]", + "uploadedPrivateKeyPassPhrase": "[steps('section_sslConfiguration').uploadedCustomSSLSettings.uploadedPrivateKeyPassPhrase]", + "uploadedKeyStoreData": "[steps('section_ohs').uploadedCustomSSLSettings.uploadedKeyStoreData]", + "uploadedKeyStorePassword": "[steps('section_ohs').uploadedCustomSSLSettings.uploadedKeyStorePassword]", + "uploadedKeyStoreType": "[steps('section_ohs').uploadedCustomSSLSettings.uploadedKeyStoreType]", + "virtualNetworkName": "[steps('section_networkingConfiguration').virtualNetwork.name]", + "virtualNetworkResourceGroupName": "[steps('section_networkingConfiguration').virtualNetwork.resourceGroup]", + "virtualNetworkNewOrExisting": "[steps('section_networkingConfiguration').virtualNetwork.newOrExisting]" + } + } +} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/dynamic_clusterdeploy.parameters.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/dynamic_clusterdeploy.parameters.json index 20a17a13e..6624b9dd4 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/dynamic_clusterdeploy.parameters.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/dynamic_clusterdeploy.parameters.json @@ -41,7 +41,7 @@ "dynamicClusterSize":{ "value": "GEN-UNIQUE" }, - "vmSizeSelect":{ + "vmSize":{ "value": "GEN-UNIQUE" } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/mainTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/mainTemplate.json index 5f9ab4dbc..86c52e4e9 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/mainTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/mainTemplate.json @@ -16,24 +16,6 @@ }, "defaultValue": "" }, - "aadsPortNumber": { - "defaultValue": "636", - "type": "string", - "metadata": { - "description": "Accessible port of the LDAP server." - } - }, - "aadsPublicIP": { - "defaultValue": "", - "type": "string" - }, - "aadsServerHost": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "The LDAP server host." - } - }, "adminPasswordOrKey": { "type": "securestring", "metadata": { @@ -47,11 +29,11 @@ "description": "User name for the Virtual Machine." } }, - "adminVMName": { - "defaultValue": "adminVM", + "adminVMNamePrefix": { + "defaultValue": "admin", "type": "string", "metadata": { - "description": "Admin Server hosting VM name." + "description": "Admin Server hosting VM name prefix." } }, "authenticationType": { @@ -72,6 +54,20 @@ "description": "One of the supported database types" } }, + "dbGlobalTranPro": { + "defaultValue": "OnePhaseCommit", + "type": "string", + "metadata": { + "description": "Determines the transaction protocol (global transaction processing behavior) for the data source." + } + }, + "dbIdentity": { + "defaultValue": {}, + "type": "object", + "metadata": { + "description": "Managed identity that has access to the data source." + } + }, "dbPassword": { "defaultValue": "", "type": "securestring", @@ -104,15 +100,6 @@ "description": "Unique DNS Name for the Public IP used to access the Virtual Machine." } }, - "dnszoneIdentity": { - "type": "Object", - "defaultValue": { - "type": "UserAssigned", - "userAssignedIdentities": { - "/subscriptions/subscriptionId/resourceGroups/TestResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/TestUserIdentity1": {} - } - } - }, "dnszoneName": { "defaultValue": "contoso.xyz", "type": "string", @@ -155,34 +142,6 @@ "description": "Initial Number of Managed Servers that will be configured in the Dynamic Cluster" } }, - "elasticsearchEndpoint": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Endpoint of the Elasticsearch instance." - } - }, - "elasticsearchPassword": { - "type": "securestring", - "defaultValue": "[newGuid()]", - "metadata": { - "description": "The credentials to distibute message with REST API to Elasticsearch instance." - } - }, - "elasticsearchUserName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "The credentials to distibute message with REST API to Elasticsearch instance." - } - }, - "enableAAD": { - "defaultValue": false, - "type": "bool", - "metadata": { - "description": "Bool value, if it's set to true, will enable Azure Active Directory after WebLogic Server starts." - } - }, "enableCoherence": { "defaultValue": false, "type": "bool", @@ -211,20 +170,31 @@ "description": "If true, use the supplied parameters to connect the cluster to a pre-provisioned database." } }, - "enableELK": { + "enableOHS": { "defaultValue": false, "type": "bool", "metadata": { - "description": "If true, use the supplied parameters to distribute WebLogic Server logs to the Elasticsearch instance." + "description": "Bool value, if it's set to true, it will setup OHS and configures for WebLogic Server cluster" } }, - "enableOHS": { + "enablePswlessConnection": { "defaultValue": false, "type": "bool", "metadata": { - "description": "Bool value, if it's set to true, it will setup OHS and configures for WebLogic Server cluster" + "description": "True to enable passwordless JDBC connection." + } + }, + "guidValue": { + "type": "string", + "defaultValue": "[newGuid()]", + "metadata": { + "description": "A unique value to ensure the generated names are unique." } }, + "guidTag": { + "type": "string", + "defaultValue": "[newGuid()]" + }, "hasDNSZones": { "type": "bool", "defaultValue": false, @@ -295,70 +265,6 @@ }, "defaultValue": "" }, - "enabledForTemplateDeployment": { - "type": "bool", - "metadata": { - "description": "Property to specify whether Azure Resource Manager is permitted to retrieve secrets from the key vault." - }, - "defaultValue": true - }, - "keyVaultSku": { - "defaultValue": "Standard", - "type": "string", - "metadata": { - "description": "Price tier for Key Vault." - } - }, - "sslConfigurationAccessOption": { - "type": "string", - "metadata": { - "description": "Options to provide required configuration for SSL configuration" - }, - "allowedValues": [ - "uploadConfig", - "keyVaultStoredConfig" - ], - "defaultValue": "keyVaultStoredConfig" - }, - "keyType": { - "type": "string", - "defaultValue": "PKCS12", - "allowedValues": [ - "JKS", - "PKCS12" - ], - "metadata": { - "description": "Provide Key type is JKS or PKCS12 signed certificates for OHS. Default is PKCS12 format" - } - }, - "keyVaultName": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "KeyVault Name where certificates are stored for OHS" - } - }, - "keyVaultResourceGroup": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "Resource group name in current subscription containing the KeyVault for OHS" - } - }, - "keyVaultSSLCertDataSecretName": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "The name of the secret in the specified KeyVault whose value is the SSL Certificate Data for OHS" - } - }, - "keyVaultSSLCertPasswordSecretName": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "The name of the secret in the specified KeyVault whose value is the password for the SSL Certificate for OHS" - } - }, "location": { "type": "string", "defaultValue": "[resourceGroup().location]", @@ -366,14 +272,6 @@ "description": "Location for all resources." } }, - "logsToIntegrate": { - "type": "array", - "defaultValue": ["HTTPAccessLog", "ServerLog", "DomainLog", "DataSourceLog", "StandardErrorAndOutput", "NodeManagerLog"], - "allowedValues": ["HTTPAccessLog", "ServerLog", "DomainLog", "DataSourceLog", "StandardErrorAndOutput", "NodeManagerLog"], - "metadata": { - "description": "Specify the expeted logs to integrate, you must input at least one log." - } - }, "managedServerPrefix": { "defaultValue": "msp", "type": "string", @@ -437,8 +335,8 @@ "description": "The Oracle Linux image with OHS and Java preinstalled. Semicolon separated string of Sku, URN, and Version" } }, - "ohsVMName": { - "defaultValue": "ohsVM", + "ohsVMNamePrefix": { + "defaultValue": "ohs", "type": "string", "metadata": { "description": "OHS Server hosting VM name." @@ -474,29 +372,28 @@ }, "skuUrnVersion": { "type": "string", - "defaultValue": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "defaultValue": "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", "allowedValues": [ - "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest", - "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest", + "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", + "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest", + "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest", + "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest", + "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest", + "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest", "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest", "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest", - "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" + "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest", + "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel76;Oracle:weblogic-122140-jdk8-rhel76:owls-122140-jdk8-rhel76;latest", + "owls-141100-jdk8-rhel76;Oracle:weblogic-141100-jdk8-rhel76:owls-141100-jdk8-rhel76;latest", + "owls-141100-jdk11-rhel76;Oracle:weblogic-141100-jdk11-rhel76:owls-141100-jdk11-rhel76;latest" ], "metadata": { "description": "The Oracle Linux image with Weblogic and Java preinstalled. Semicolon separated string of Sku, URN, and Version" } }, - "ohsSSLConfigAccessOption": { - "type": "string", - "metadata": { - "description": "Options to provide required configuration for SSL configuration" - }, - "allowedValues": [ - "uploadConfig", - "keyVaultStoredConfig" - ], - "defaultValue": "keyVaultStoredConfig" - }, "usePreviewImage": { "type": "bool", "defaultValue": false, @@ -532,7 +429,7 @@ "description": "SSL Certificate Data type" } }, - "vmSizeSelect": { + "vmSize": { "defaultValue": "Standard_A2_v2", "type": "string", "metadata": { @@ -546,53 +443,59 @@ "description": "Select appropriate VM Size for Coherence" } }, - "wlsDomainName": { - "defaultValue": "wlsd", + "virtualNetworkNewOrExisting": { "type": "string", + "defaultValue": "new", + "allowedValues": [ + "new", + "existing" + ], "metadata": { - "description": "Provide Weblogic domain name" + "description": "Specify whether to create a new or existing virtual network for the VM." } }, - "wlsLDAPGroupBaseDN": { - "defaultValue": "", - "type": "securestring", + "virtualNetworkName": { + "type": "string", + "defaultValue": "[concat('wlsdcluster-vnet-', uniqueString(utcNow()))]", "metadata": { - "description": "The base distinguished name (DN) of the tree in the LDAP directory that contains groups." + "description": "Name of the existing or new VNET" } }, - "wlsLDAPPrincipal": { - "defaultValue": "", - "type": "securestring", + "virtualNetworkResourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", "metadata": { - "description": "The Distinguished Name (DN) of the LDAP user that WebLogic Server should use to connect to the LDAP server." + "description": "Resource group of Virtual network" } }, - "wlsLDAPPrincipalPassword": { - "defaultValue": "[newGuid()]", - "type": "securestring", + "addressPrefixes": { + "type": "array", + "defaultValue": [ + "10.0.0.0/16" + ], "metadata": { - "description": "The credential (usually a password) used to connect to the LDAP server." + "description": "Address prefix of the VNET." } }, - "wlsLDAPProviderName": { - "defaultValue": "AzureActiveDirectoryProvider", + "subnetName": { "type": "string", + "defaultValue": "wls-subnet", "metadata": { - "description": "The value used for creating authentication provider name of WebLogic Server." + "description": "Name of the existing or new Subnet" } }, - "wlsLDAPSSLCertificate": { - "defaultValue": "", - "type": "securestring", + "subnetPrefix": { + "type": "string", + "defaultValue": "10.0.0.0/24", "metadata": { - "description": "Client certificate that will be imported to trust store of SSL." + "description": "Address prefix of the subnet" } }, - "wlsLDAPUserBaseDN": { - "defaultValue": "", - "type": "securestring", + "wlsDomainName": { + "defaultValue": "wlsd", + "type": "string", "metadata": { - "description": "The base distinguished name (DN) of the tree in the LDAP directory that contains users." + "description": "Provide Weblogic domain name" } }, "wlsPassword": { @@ -621,110 +524,33 @@ "metadata": { "description": "Boolean value indicating, if custom SSL is enabled or not" } - }, - "adminSSLKeyVaultResourceGroup": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "Resource group name in current subscription containing the KeyVault for SSL Configuration of WebLogic Administration Server" - } - }, - "adminSSLKeyVaultName": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "KeyVault Name for SSL Configuration of WebLogic Administration Server" - } - }, - "keyVaultCustomIdentityKeyStoreDataSecretName": { - "type": "string", - "metadata": { - "description": "Secret name in KeyVault containing Weblogic Custom Identity Keystore Data" - }, - "defaultValue": "CustomIdentityKeyStoreDataSecret" - }, - "keyVaultCustomIdentityKeyStorePassPhraseSecretName": { - "type": "string", - "metadata": { - "description": "Secret name in KeyVault containing Weblogic Custom Identity Keystore Passphrase" - }, - "defaultValue": "CustomIdentityKeyStorePassPhraseSecret" - }, - "keyVaultCustomIdentityKeyStoreType": { - "type": "string", - "metadata": { - "description": "Weblogic Custom Identity Keystore Type" - }, - "defaultValue": "JKS" - }, - "keyVaultCustomTrustKeyStoreDataSecretName": { - "type": "string", - "metadata": { - "description": "Secret name in KeyVault containing Weblogic Custom Trust Store Data" - }, - "defaultValue": "CustomTrustStoreDataSecret" - }, - "keyVaultCustomTrustKeyStorePassPhraseSecretName": { - "type": "string", - "metadata": { - "description": "Secret name in KeyVault containing Weblogic Custom Trust Store Passphrase" - }, - "defaultValue": "CustomTrustStorePassPhraseSecret" - }, - "keyVaultCustomTrustKeyStoreType": { - "type": "string", - "metadata": { - "description": "Weblogic Custom Trust Store Type" - }, - "defaultValue": "JKS" - }, - "keyVaultPrivateKeyAliasSecretName": { - "type": "string", - "metadata": { - "description": "Secret name in KeyVault containing Weblogic Server Private Key Alias" - }, - "defaultValue": "ServerPrivateKeyAlias" - }, - "keyVaultPrivateKeyPassPhraseSecretName": { - "type": "string", - "metadata": { - "description": "Secret name in KeyVault containing Weblogic Server Private KeyPassPhrase" - }, - "defaultValue": "ServerPrivateKeyPassPhraseSecret" - }, - "utcValue": { - "type": "string", - "defaultValue": "[utcNow()]", - "metadata": { - "description": "Current deployment time. Used as a tag in deployment script." - } } }, "variables": { - "const_ohsSSLConfigAccessOptionUploadConfig": "uploadConfig", - "const_ohsSSLConfigAccessOptionKeyVaultStoredConfig": "keyVaultStoredConfig", - "const_sslConfigurationAccessOptionUploadConfig": "uploadConfig", - "const_sslConfigurationAccessOptionKeyVaultStoredConfig": "keyVaultStoredConfig", - "const_currentSubscription": "[subscription().subscriptionId]", - "name_aadLinkedTemplateName": "aadNestedTemplate.json", - "name_clusterLinkedTemplateName": "clusterTemplate.json", + "const_globalResourceNameSuffix": "[uniqueString(parameters('guidValue'))]", + "const_guidTag": "[uniqueString(parameters('guidTag'))]", + "name_adminVM": "[concat(parameters('adminVMNamePrefix'), variables('const_globalResourceNameSuffix'), 'VM')]", + "name_clusterCustomSSLTemplate": "clusterCustomSSLLinkedTemplate", "name_clusterCustomSSLLinkedTemplateName": "clusterCustomSSLTemplate.json", + "name_clusterLinkedTemplateName": "clusterTemplate.json", + "name_clusterTemplate": "clusterLinkedTemplate", + "name_uamiForPostDeploymentScript" : "uamiForPostDeploymentScript", + "name_coherenceTemplateName": "coherenceTemplate.json", "name_dbLinkedTemplateName": "dbTemplate.json", "name_dnszonesLinkedTemplateName": "dnszonesTemplate.json", - "name_elkLinkedTemplateName": "elkNestedTemplate.json", - "name_coherenceTemplateName": "coherenceTemplate.json", - "name_ohsLinkedTemplateName": "ohsNestedTemplate.json", + "name_postDeploymentUAMIRolesTemplate" : "postDeploymentUAMIRolesTemplate.json", + "name_postDeploymentTemplate": "postDeploymentTemplate.json", + "name_managedVMNamePrefix": "[concat(parameters('managedServerPrefix'), variables('const_globalResourceNameSuffix'))]", + "name_networkSecurityGroup": "[concat(parameters('dnsLabelPrefix'), '-nsg-', variables('const_globalResourceNameSuffix'))]", "name_nsgLinkedTemplateName": "nsgNestedTemplate.json", - "clusterTemplateRef": "[concat('cluster',if(parameters('enableCustomSSL'),'CustomSSL',''),'LinkedTemplate')]", - "name_clusterTemplate": "clusterLinkedTemplate", - "name_clusterCustomSSLTemplate": "clusterCustomSSLLinkedTemplate", - "name_ohsKeyVaultNestedTemplate": "_ohsKeyVaultNestedTemplate.json", - "name_keyVaultNestedTemplate": "_sslKeyVaultNestedTemplate.json", - "name_keyVaultName": "[take(concat('wls-kv', uniqueString(parameters('utcValue'))), 24)]" + "name_ohsLinkedTemplateName": "ohsNestedTemplate.json", + "name_ohsVMName": "[concat(parameters('ohsVMNamePrefix'), variables('const_globalResourceNameSuffix'), 'VM')]", + "ref_clusterTemplate": "[concat('cluster',if(parameters('enableCustomSSL'),'CustomSSL',''),'LinkedTemplate')]" }, - "resources": [{ + "resources": [ + { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${dynamic.start}", "properties": { "mode": "Incremental", @@ -735,54 +561,9 @@ } } }, - { - "name": "keyVaultNestedTemplate", - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "condition": "[and(parameters('enableCustomSSL'), equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionUploadConfig')))]", - "properties": { - "mode": "Incremental", - "templateLink": { - "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_keyVaultNestedTemplate')))]", - "contentVersion": "1.0.0.0" - }, - "parameters": { - "uploadedCustomIdentityKeyStoreData": { - "value": "[parameters('uploadedCustomIdentityKeyStoreData')]" - }, - "uploadedCustomIdentityKeyStorePassphrase": { - "value": "[parameters('uploadedCustomIdentityKeyStorePassphrase')]" - }, - "uploadedCustomTrustKeyStoreData": { - "value": "[parameters('uploadedCustomTrustKeyStoreData')]" - }, - "uploadedCustomTrustKeyStorePassPhrase": { - "value": "[parameters('uploadedCustomTrustKeyStorePassPhrase')]" - }, - "uploadedPrivateKeyAlias": { - "value": "[parameters('uploadedPrivateKeyAlias')]" - }, - "uploadedPrivateKeyPassPhrase": { - "value": "[parameters('uploadedPrivateKeyPassPhrase')]" - }, - "enabledForTemplateDeployment": { - "value": "[parameters('enabledForTemplateDeployment')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "sku": { - "value": "[parameters('keyVaultSku')]" - }, - "keyVaultName": { - "value": "[variables('name_keyVaultName')]" - } - } - } - }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "[variables('name_clusterTemplate')]", "condition": "[not(parameters('enableCustomSSL'))]", "properties": { @@ -798,6 +579,12 @@ "_artifactsLocationSasToken": { "value": "[parameters('_artifactsLocationSasToken')]" }, + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" + }, + "const_guidTag":{ + "value": "[variables('const_guidTag')]" + }, "adminPasswordOrKey": { "value": "[parameters('adminPasswordOrKey')]" }, @@ -805,11 +592,14 @@ "value": "[parameters('adminUsername')]" }, "adminVMName": { - "value": "[parameters('adminVMName')]" + "value": "[variables('name_adminVM')]" }, "authenticationType": { "value": "[parameters('authenticationType')]" }, + "addressPrefixes": { + "value": "[parameters('addressPrefixes')]" + }, "dnsLabelPrefix": { "value": "[parameters('dnsLabelPrefix')]" }, @@ -822,23 +612,44 @@ "managedServerPrefix": { "value": "[parameters('managedServerPrefix')]" }, + "managedVMPrefix": { + "value": "[variables('name_managedVMNamePrefix')]" + }, "maxDynamicClusterSize": { "value": "[parameters('maxDynamicClusterSize')]" }, + "nsgName": { + "value": "[variables('name_networkSecurityGroup')]" + }, "portsToExpose": { "value": "[parameters('portsToExpose')]" }, "skuUrnVersion": { "value": "[parameters('skuUrnVersion')]" }, + "subnetName": { + "value": "[parameters('subnetName')]" + }, + "subnetPrefix": { + "value": "[parameters('subnetPrefix')]" + }, "usePreviewImage": { "value": "[parameters('usePreviewImage')]" }, "useSystemAssignedManagedIdentity": { "value": "[parameters('useSystemAssignedManagedIdentity')]" }, - "vmSizeSelect": { - "value": "[parameters('vmSizeSelect')]" + "vmSize": { + "value": "[parameters('vmSize')]" + }, + "virtualNetworkNewOrExisting": { + "value": "[parameters('virtualNetworkNewOrExisting')]" + }, + "virtualNetworkName": { + "value": "[parameters('virtualNetworkName')]" + }, + "virtualNetworkResourceGroupName": { + "value": "[parameters('virtualNetworkResourceGroupName')]" }, "wlsDomainName": { "value": "[parameters('wlsDomainName')]" @@ -851,13 +662,19 @@ }, "enableHTTPAdminListenPort": { "value": "[parameters('enableHTTPAdminListenPort')]" + }, + "enableDNSConfiguration": { + "value": "[parameters('enableCustomDNS')]" + }, + "customDNSNameForAdminServer": { + "value": "[if(parameters('enableCustomDNS'), format('{0}.{1}', parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')),'')]" } } } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "[variables('name_clusterCustomSSLTemplate')]", "condition": "[parameters('enableCustomSSL')]", "properties": { @@ -873,6 +690,12 @@ "_artifactsLocationSasToken": { "value": "[parameters('_artifactsLocationSasToken')]" }, + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" + }, + "const_guidTag":{ + "value": "[variables('const_guidTag')]" + }, "adminPasswordOrKey": { "value": "[parameters('adminPasswordOrKey')]" }, @@ -880,11 +703,14 @@ "value": "[parameters('adminUsername')]" }, "adminVMName": { - "value": "[parameters('adminVMName')]" + "value": "[variables('name_adminVM')]" }, "authenticationType": { "value": "[parameters('authenticationType')]" }, + "addressPrefixes": { + "value": "[parameters('addressPrefixes')]" + }, "dnsLabelPrefix": { "value": "[parameters('dnsLabelPrefix')]" }, @@ -897,23 +723,44 @@ "managedServerPrefix": { "value": "[parameters('managedServerPrefix')]" }, + "managedVMPrefix": { + "value": "[variables('name_managedVMNamePrefix')]" + }, "maxDynamicClusterSize": { "value": "[parameters('maxDynamicClusterSize')]" }, + "nsgName": { + "value": "[variables('name_networkSecurityGroup')]" + }, "portsToExpose": { "value": "[parameters('portsToExpose')]" }, "skuUrnVersion": { "value": "[parameters('skuUrnVersion')]" }, + "subnetName": { + "value": "[parameters('subnetName')]" + }, + "subnetPrefix": { + "value": "[parameters('subnetPrefix')]" + }, "usePreviewImage": { "value": "[parameters('usePreviewImage')]" }, "useSystemAssignedManagedIdentity": { "value": "[parameters('useSystemAssignedManagedIdentity')]" }, - "vmSizeSelect": { - "value": "[parameters('vmSizeSelect')]" + "vmSize": { + "value": "[parameters('vmSize')]" + }, + "virtualNetworkNewOrExisting": { + "value": "[parameters('virtualNetworkNewOrExisting')]" + }, + "virtualNetworkName": { + "value": "[parameters('virtualNetworkName')]" + }, + "virtualNetworkResourceGroupName": { + "value": "[parameters('virtualNetworkResourceGroupName')]" }, "wlsDomainName": { "value": "[parameters('wlsDomainName')]" @@ -927,105 +774,46 @@ "enableHTTPAdminListenPort": { "value": "[parameters('enableHTTPAdminListenPort')]" }, + "enableDNSConfiguration": { + "value": "[parameters('enableCustomDNS')]" + }, + "customDNSNameForAdminServer": { + "value": "[if(parameters('enableCustomDNS'), format('{0}.{1}', parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')),'')]" + }, "enableCustomSSL": { "value": "[parameters('enableCustomSSL')]" }, - "keyVaultCustomIdentityKeyStoreData": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomIdentityKeyStoreDataSecretName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.customIdentityKeyStoreDataSecretName.value)]" - } - }, - "keyVaultCustomIdentityKeyStorePassPhrase": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomIdentityKeyStorePassPhraseSecretName'), reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.customIdentityKeyStorePassPhraseSecretName.value)]" - } - }, - "keyVaultCustomIdentityKeyStoreType": { - "value": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomIdentityKeyStoreType'), parameters('uploadedCustomIdentityKeyStoreType'))]" - }, - "keyVaultCustomTrustKeyStoreData": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStoreDataSecretName'), reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.customTrustKeyStoretDataSecretName.value)]" - } - }, - "keyVaultCustomTrustKeyStorePassPhrase": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStorePassPhraseSecretName'), reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.customTrustKeyStorePassPhraseSecretName.value)]" - } - }, - "keyVaultCustomTrustKeyStoreType": { - "value": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStoreType'), parameters('uploadedCustomTrustKeyStoreType'))]" - }, - "keyVaultPrivateKeyAlias": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultPrivateKeyAliasSecretName'), reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.privateKeyAliasSecretName.value)]" - } - }, - "keyVaultPrivateKeyPassPhrase": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultPrivateKeyPassPhraseSecretName'), reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.privateKeyPassPhraseSecretName.value)]" - } - } - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'keyVaultNestedTemplate')]" - ] - }, - { - "name": "ohsKeyVaultNestedTemplate", - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "condition": "[and(parameters('enableOHS'), equals(parameters('ohsSSLConfigAccessOption'), variables('const_ohsSSLConfigAccessOptionUploadConfig')))]", - "properties": { - "mode": "Incremental", - "templateLink": { - "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_ohsKeyVaultNestedTemplate')))]", - "contentVersion": "1.0.0.0" - }, - "parameters": { - "uploadedKeyStoreData": { - "value": "[parameters('uploadedKeyStoreData')]" + "sslCustomIdentityKeyStoreData": { + "value": "[parameters('uploadedCustomIdentityKeyStoreData')]" }, - "uploadedKeyStorePassword": { - "value": "[parameters('uploadedKeyStorePassword')]" + "sslCustomIdentityKeyStorePassPhrase": { + "value": "[parameters('uploadedCustomIdentityKeyStorePassphrase')]" }, - "location": { - "value": "[parameters('location')]" + "sslCustomIdentityKeyStoreType": { + "value": "[parameters('uploadedCustomIdentityKeyStoreType')]" }, - "sku": { - "value": "[parameters('keyVaultSku')]" + "sslCustomTrustKeyStoreData": { + "value": "[parameters('uploadedCustomTrustKeyStoreData')]" + }, + "sslCustomTrustKeyStorePassPhrase": { + "value": "[parameters('uploadedCustomTrustKeyStorePassPhrase')]" }, - "keyVaultName": { - "value": "[variables('name_keyVaultName')]" + "sslCustomTrustKeyStoreType": { + "value": "[parameters('uploadedCustomTrustKeyStoreType')]" + }, + "sslPrivateKeyAlias": { + "value": "[parameters('uploadedPrivateKeyAlias')]" + }, + "sslPrivateKeyPassPhrase": { + "value": "[parameters('uploadedPrivateKeyPassPhrase')]" } } - }, - "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'keyVaultNestedTemplate')]" - ] + } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", "name": "networkSecurityLinkedTemplate", "properties": { "mode": "Incremental", @@ -1044,22 +832,22 @@ "value": "[parameters('enableOHS')]" }, "networkSecurityGroupName": { - "value": "[concat(parameters('dnsLabelPrefix'), '-nsg')]" + "value": "[variables('name_networkSecurityGroup')]" } } }, "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', variables('clusterTemplateRef'))]", + "[resourceId('Microsoft.Resources/deployments', variables('ref_clusterTemplate'))]", "[resourceId('Microsoft.Resources/deployments', 'ohsLinkedTemplate')]" ] }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "dbLinkedTemplate", "condition": "[parameters('enableDB')]", "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', variables('clusterTemplateRef'))]" + "[resourceId('Microsoft.Resources/deployments', variables('ref_clusterTemplate'))]" ], "properties": { "mode": "Incremental", @@ -1071,15 +859,24 @@ "_artifactsLocation": { "value": "[parameters('_artifactsLocation')]" }, + "wlsDomainName": { + "value": "[parameters('wlsDomainName')]" + }, "_artifactsLocationSasToken": { "value": "[parameters('_artifactsLocationSasToken')]" }, "adminVMName": { - "value": "[parameters('adminVMName')]" + "value": "[variables('name_adminVM')]" }, "databaseType": { "value": "[parameters('databaseType')]" }, + "dbGlobalTranPro": { + "value": "[parameters('dbGlobalTranPro')]" + }, + "dbIdentity": { + "value": "[parameters('dbIdentity')]" + }, "dbPassword": { "value": "[parameters('dbPassword')]" }, @@ -1089,232 +886,24 @@ "dsConnectionURL": { "value": "[parameters('dsConnectionURL')]" }, + "enablePswlessConnection": { + "value": "[parameters('enablePswlessConnection')]" + }, "jdbcDataSourceName": { "value": "[parameters('jdbcDataSourceName')]" }, "location": { "value": "[parameters('location')]" }, - "wlsPassword": { - "value": "[parameters('wlsPassword')]" - }, - "wlsUserName": { - "value": "[parameters('wlsUserName')]" - } - } - } - }, - { - "name": "aadLinkedTemplate", - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'dbLinkedTemplate')]" - ], - "condition": "[and(parameters('enableAAD'),not(parameters('enableCustomSSL')))]", - "properties": { - "mode": "Incremental", - "templateLink": { - "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_aadLinkedTemplateName')))]", - "contentVersion": "1.0.0.0" - }, - "parameters": { - "_artifactsLocation": { - "value": "[parameters('_artifactsLocation')]" - }, - "_artifactsLocationSasToken": { - "value": "[parameters('_artifactsLocationSasToken')]" - }, - "aadsPortNumber": { - "value": "[parameters('aadsPortNumber')]" - }, - "aadsPublicIP": { - "value": "[parameters('aadsPublicIP')]" - }, - "aadsServerHost": { - "value": "[parameters('aadsServerHost')]" - }, - "adminVMName": { - "value": "[parameters('adminVMName')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "managedServerPrefix": { - "value": "[parameters('managedServerPrefix')]" - }, - "dynamicClusterSize": { - "value": "[parameters('dynamicClusterSize')]" - }, - "wlsDomainName": { - "value": "[parameters('wlsDomainName')]" - }, - "wlsLDAPGroupBaseDN": { - "value": "[parameters('wlsLDAPGroupBaseDN')]" - }, - "wlsLDAPPrincipal": { - "value": "[parameters('wlsLDAPPrincipal')]" - }, - "wlsLDAPPrincipalPassword": { - "value": "[parameters('wlsLDAPPrincipalPassword')]" - }, - "wlsLDAPProviderName": { - "value": "[parameters('wlsLDAPProviderName')]" - }, - "wlsLDAPSSLCertificate": { - "value": "[parameters('wlsLDAPSSLCertificate')]" - }, - "wlsLDAPUserBaseDN": { - "value": "[parameters('wlsLDAPUserBaseDN')]" - }, - "wlsPassword": { - "value": "[parameters('wlsPassword')]" - }, - "wlsUserName": { - "value": "[parameters('wlsUserName')]" - } - } - } - }, - { - "name": "aadLinkedTemplateWithCustomSSL", - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'dbLinkedTemplate')]", - "[resourceId('Microsoft.Resources/deployments', 'keyVaultNestedTemplate')]" - ], - "condition": "[and(parameters('enableAAD'),parameters('enableCustomSSL'))]", - "properties": { - "mode": "Incremental", - "templateLink": { - "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_aadLinkedTemplateName')))]", - "contentVersion": "1.0.0.0" - }, - "parameters": { - "_artifactsLocation": { - "value": "[parameters('_artifactsLocation')]" - }, - "_artifactsLocationSasToken": { - "value": "[parameters('_artifactsLocationSasToken')]" - }, - "aadsPortNumber": { - "value": "[parameters('aadsPortNumber')]" - }, - "aadsPublicIP": { - "value": "[parameters('aadsPublicIP')]" - }, - "aadsServerHost": { - "value": "[parameters('aadsServerHost')]" - }, - "adminVMName": { - "value": "[parameters('adminVMName')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "managedServerPrefix": { - "value": "[parameters('managedServerPrefix')]" - }, - "dynamicClusterSize": { - "value": "[parameters('dynamicClusterSize')]" - }, - "wlsDomainName": { - "value": "[parameters('wlsDomainName')]" - }, - "wlsLDAPGroupBaseDN": { - "value": "[parameters('wlsLDAPGroupBaseDN')]" - }, - "wlsLDAPPrincipal": { - "value": "[parameters('wlsLDAPPrincipal')]" - }, - "wlsLDAPPrincipalPassword": { - "value": "[parameters('wlsLDAPPrincipalPassword')]" - }, - "wlsLDAPProviderName": { - "value": "[parameters('wlsLDAPProviderName')]" - }, - "wlsLDAPSSLCertificate": { - "value": "[parameters('wlsLDAPSSLCertificate')]" - }, - "wlsLDAPUserBaseDN": { - "value": "[parameters('wlsLDAPUserBaseDN')]" - }, - "wlsPassword": { - "value": "[parameters('wlsPassword')]" - }, - "wlsUserName": { - "value": "[parameters('wlsUserName')]" - }, - "enableCustomSSL": { - "value": "[parameters('enableCustomSSL')]" - }, - "keyVaultCustomTrustKeyStorePassPhrase": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStorePassPhraseSecretName'), reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.customTrustKeyStorePassPhraseSecretName.value)]" - } - }, - "keyVaultCustomTrustKeyStoreType": { - "value": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStoreType'), parameters('uploadedCustomTrustKeyStoreType'))]" - } - } - } - }, - { - "name": "elkLinkedTemplate", - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'aadLinkedTemplate')]", - "[resourceId('Microsoft.Resources/deployments', 'aadLinkedTemplateWithCustomSSL')]" - ], - "condition": "[parameters('enableELK')]", - "properties": { - "mode": "Incremental", - "templateLink": { - "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_elkLinkedTemplateName')))]", - "contentVersion": "1.0.0.0" - }, - "parameters": { - "_artifactsLocation": { - "value": "[parameters('_artifactsLocation')]" - }, - "_artifactsLocationSasToken": { - "value": "[parameters('_artifactsLocationSasToken')]" - }, - "adminVMName": { - "value": "[parameters('adminVMName')]" - }, - "elasticsearchEndpoint": { - "value": "[parameters('elasticsearchEndpoint')]" - }, - "elasticsearchPassword": { - "value": "[parameters('elasticsearchPassword')]" - }, - "elasticsearchUserName": { - "value": "[parameters('elasticsearchUserName')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "logsToIntegrate": { - "value": "[parameters('logsToIntegrate')]" - }, "managedServerPrefix": { "value": "[parameters('managedServerPrefix')]" }, - "maxDynamicClusterSize": { - "value": "[parameters('maxDynamicClusterSize')]" + "managedVMNamePrefix": { + "value": "[variables('name_managedVMNamePrefix')]" }, "numberOfManagedApplicationInstances": { "value": "[parameters('dynamicClusterSize')]" }, - "wlsDomainName": { - "value": "[parameters('wlsDomainName')]" - }, "wlsPassword": { "value": "[parameters('wlsPassword')]" }, @@ -1328,9 +917,9 @@ "name": "coherenceTemplate", "type": "Microsoft.Resources/deployments", "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'elkLinkedTemplate')]" + "[resourceId('Microsoft.Resources/deployments', 'dbLinkedTemplate')]" ], - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "condition": "[and(parameters('enableCoherence'),not(parameters('enableCustomSSL')))]", "properties": { "mode": "Incremental", @@ -1345,6 +934,9 @@ "_artifactsLocationSasToken": { "value": "[parameters('_artifactsLocationSasToken')]" }, + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" + }, "adminPasswordOrKey": { "value": "[parameters('adminPasswordOrKey')]" }, @@ -1355,46 +947,34 @@ "value": "[parameters('authenticationType')]" }, "adminVMName": { - "value": "[parameters('adminVMName')]" + "value": "[variables('name_adminVM')]" }, "dnsLabelPrefix": { "value": "[parameters('dnsLabelPrefix')]" }, - "elasticsearchEndpoint": { - "value": "[parameters('elasticsearchEndpoint')]" - }, - "elasticsearchPassword": { - "value": "[parameters('elasticsearchPassword')]" - }, - "elasticsearchUserName": { - "value": "[parameters('elasticsearchUserName')]" - }, "enableCoherenceWebLocalStorage": { "value": "[parameters('enableCoherenceWebLocalStorage')]" }, - "enableELK": { - "value": "[parameters('enableELK')]" - }, "location": { "value": "[parameters('location')]" }, - "logIndex": { - "value": "[if(parameters('enableELK'), reference('elkLinkedTemplate', '${azure.apiVersion}').outputs.logIndex.value, '')]" - }, - "logsToIntegrate": { - "value": "[parameters('logsToIntegrate')]" - }, "managedServerPrefix": { "value": "[parameters('managedServerPrefix')]" }, + "managedVMNamePrefix": { + "value": "[variables('name_managedVMNamePrefix')]" + }, "numberOfCoherenceCacheInstances": { "value": "[parameters('numberOfCoherenceCacheInstances')]" }, "skuUrnVersion": { "value": "[parameters('skuUrnVersion')]" }, + "subnetName": { + "value": "[parameters('subnetName')]" + }, "storageAccountName": { - "value": "[reference(variables('clusterTemplateRef'), '${azure.apiVersion}').outputs.storageAccountName.value]" + "value": "[reference(variables('ref_clusterTemplate'), '${azure.apiVersionForDeployment}').outputs.storageAccountName.value]" }, "usePreviewImage": { "value": "[parameters('usePreviewImage')]" @@ -1402,6 +982,12 @@ "vmSizeSelectForCoherence": { "value": "[parameters('vmSizeSelectForCoherence')]" }, + "virtualNetworkResourceGroupName": { + "value": "[parameters('virtualNetworkResourceGroupName')]" + }, + "virtualNetworkName": { + "value": "[parameters('virtualNetworkName')]" + }, "wlsDomainName": { "value": "[parameters('wlsDomainName')]" }, @@ -1413,6 +999,12 @@ }, "enableCustomSSL": { "value": "[parameters('enableCustomSSL')]" + }, + "enableDNSConfiguration": { + "value": "[parameters('enableCustomDNS')]" + }, + "customDNSNameForAdminServer": { + "value": "[if(parameters('enableCustomDNS'), format('{0}.{1}', parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')),'')]" } } } @@ -1421,9 +1013,9 @@ "name": "coherenceTemplateWithCustomSSL", "type": "Microsoft.Resources/deployments", "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'elkLinkedTemplate')]" + "[resourceId('Microsoft.Resources/deployments', 'dbLinkedTemplate')]" ], - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "condition": "[and(parameters('enableCoherence'),parameters('enableCustomSSL'))]", "properties": { "mode": "Incremental", @@ -1438,6 +1030,9 @@ "_artifactsLocationSasToken": { "value": "[parameters('_artifactsLocationSasToken')]" }, + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" + }, "adminPasswordOrKey": { "value": "[parameters('adminPasswordOrKey')]" }, @@ -1448,38 +1043,23 @@ "value": "[parameters('authenticationType')]" }, "adminVMName": { - "value": "[parameters('adminVMName')]" + "value": "[variables('name_adminVM')]" }, "dnsLabelPrefix": { "value": "[parameters('dnsLabelPrefix')]" }, - "elasticsearchEndpoint": { - "value": "[parameters('elasticsearchEndpoint')]" - }, - "elasticsearchPassword": { - "value": "[parameters('elasticsearchPassword')]" - }, - "elasticsearchUserName": { - "value": "[parameters('elasticsearchUserName')]" - }, "enableCoherenceWebLocalStorage": { "value": "[parameters('enableCoherenceWebLocalStorage')]" }, - "enableELK": { - "value": "[parameters('enableELK')]" - }, "location": { "value": "[parameters('location')]" }, - "logIndex": { - "value": "[if(parameters('enableELK'), reference('elkLinkedTemplate', '${azure.apiVersion}').outputs.logIndex.value, '')]" - }, - "logsToIntegrate": { - "value": "[parameters('logsToIntegrate')]" - }, "managedServerPrefix": { "value": "[parameters('managedServerPrefix')]" }, + "managedVMNamePrefix": { + "value": "[variables('name_managedVMNamePrefix')]" + }, "numberOfCoherenceCacheInstances": { "value": "[parameters('numberOfCoherenceCacheInstances')]" }, @@ -1487,11 +1067,20 @@ "value": "[parameters('skuUrnVersion')]" }, "storageAccountName": { - "value": "[reference(variables('clusterTemplateRef'), '${azure.apiVersion}').outputs.storageAccountName.value]" + "value": "[reference(variables('ref_clusterTemplate'), '${azure.apiVersionForDeployment}').outputs.storageAccountName.value]" }, "usePreviewImage": { "value": "[parameters('usePreviewImage')]" }, + "subnetName": { + "value": "[parameters('subnetName')]" + }, + "virtualNetworkResourceGroupName": { + "value": "[parameters('virtualNetworkResourceGroupName')]" + }, + "virtualNetworkName": { + "value": "[parameters('virtualNetworkName')]" + }, "vmSizeSelectForCoherence": { "value": "[parameters('vmSizeSelectForCoherence')]" }, @@ -1504,62 +1093,38 @@ "wlsUserName": { "value": "[parameters('wlsUserName')]" }, + "enableDNSConfiguration": { + "value": "[parameters('enableCustomDNS')]" + }, + "customDNSNameForAdminServer": { + "value": "[if(parameters('enableCustomDNS'), format('{0}.{1}', parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')),'')]" + }, "enableCustomSSL": { "value": "[parameters('enableCustomSSL')]" }, - "keyVaultCustomIdentityKeyStoreData": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomIdentityKeyStoreDataSecretName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.customIdentityKeyStoreDataSecretName.value)]" - } - }, - "keyVaultCustomIdentityKeyStorePassPhrase": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomIdentityKeyStorePassPhraseSecretName'), reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.customIdentityKeyStorePassPhraseSecretName.value)]" - } - }, - "keyVaultCustomIdentityKeyStoreType": { - "value": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomIdentityKeyStoreType'), parameters('uploadedCustomIdentityKeyStoreType'))]" - }, - "keyVaultCustomTrustKeyStoreData": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStoreDataSecretName'), reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.customTrustKeyStoretDataSecretName.value)]" - } - }, - "keyVaultCustomTrustKeyStorePassPhrase": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStorePassPhraseSecretName'), reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.customTrustKeyStorePassPhraseSecretName.value)]" - } - }, - "keyVaultCustomTrustKeyStoreType": { - "value": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultCustomTrustKeyStoreType'), parameters('uploadedCustomTrustKeyStoreType'))]" - }, - "keyVaultPrivateKeyAlias": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultPrivateKeyAliasSecretName'), reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.privateKeyAliasSecretName.value)]" - } - }, - "keyVaultPrivateKeyPassPhrase": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('adminSSLKeyVaultName'),reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('sslConfigurationAccessOption'), variables('const_sslConfigurationAccessOptionKeyVaultStoredConfig')),parameters('keyVaultPrivateKeyPassPhraseSecretName'), reference('keyVaultNestedTemplate', '${azure.apiVersion}').outputs.privateKeyPassPhraseSecretName.value)]" - } + "sslCustomIdentityKeyStoreData": { + "value": "[parameters('uploadedCustomIdentityKeyStoreData')]" + }, + "sslCustomIdentityKeyStorePassPhrase": { + "value": "[parameters('uploadedCustomIdentityKeyStorePassphrase')]" + }, + "sslCustomIdentityKeyStoreType": { + "value": "[parameters('uploadedCustomIdentityKeyStoreType')]" + }, + "sslCustomTrustKeyStoreData": { + "value": "[parameters('uploadedCustomTrustKeyStoreData')]" + }, + "sslCustomTrustKeyStorePassPhrase": { + "value": "[parameters('uploadedCustomTrustKeyStorePassPhrase')]" + }, + "sslCustomTrustKeyStoreType": { + "value": "[parameters('uploadedCustomTrustKeyStoreType')]" + }, + "sslPrivateKeyAlias": { + "value": "[parameters('uploadedPrivateKeyAlias')]" + }, + "sslPrivateKeyPassPhrase": { + "value": "[parameters('uploadedPrivateKeyPassPhrase')]" } } } @@ -1568,12 +1133,11 @@ "name": "ohsLinkedTemplate", "type": "Microsoft.Resources/deployments", "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', variables('clusterTemplateRef'))]", + "[resourceId('Microsoft.Resources/deployments', variables('ref_clusterTemplate'))]", "[resourceId('Microsoft.Resources/deployments', 'coherenceTemplate')]", - "[resourceId('Microsoft.Resources/deployments', 'coherenceTemplateWithCustomSSL')]", - "[resourceId('Microsoft.Resources/deployments', 'ohsKeyVaultNestedTemplate')]" + "[resourceId('Microsoft.Resources/deployments', 'coherenceTemplateWithCustomSSL')]" ], - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "condition": "[parameters('enableOHS')]", "properties": { "mode": "Incremental", @@ -1601,11 +1165,17 @@ "value": "[parameters('dnsLabelPrefix')]" }, "storageAccountName": { - "value": "[reference(variables('clusterTemplateRef'),'${azure.apiVersion}').outputs.storageAccountName.value]" + "value": "[reference(variables('ref_clusterTemplate'),'${azure.apiVersionForDeployment}').outputs.storageAccountName.value]" + }, + "subnetName": { + "value": "[parameters('subnetName')]" }, "location": { "value": "[parameters('location')]" }, + "nsgName": { + "value": "[variables('name_networkSecurityGroup')]" + }, "ohsComponentName": { "value": "[parameters('ohsComponentName')]" }, @@ -1622,7 +1192,7 @@ "value": "[parameters('ohsSkuUrnVersion')]" }, "ohsVMName": { - "value": "[parameters('ohsVMName')]" + "value": "[variables('name_ohsVMName')]" }, "ohshttpPort": { "value": "[parameters('ohshttpPort')]" @@ -1631,33 +1201,28 @@ "value": "[parameters('ohshttpsPort')]" }, "ohsSSLKeystoreData": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('ohsSSLConfigAccessOption'), variables('const_ohsSSLConfigAccessOptionKeyVaultStoredConfig')),parameters('keyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('ohsSSLConfigAccessOption'), variables('const_ohsSSLConfigAccessOptionKeyVaultStoredConfig')),parameters('keyVaultName'),reference('ohsKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('ohsSSLConfigAccessOption'), variables('const_ohsSSLConfigAccessOptionKeyVaultStoredConfig')),parameters('keyVaultSSLCertDataSecretName'),reference('ohsKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyStoreDataSecretName.value)]" - - } + "value": "[parameters('uploadedKeyStoreData')]" }, "ohsSSLKeystorePassword": { - "reference": { - "keyVault": { - "id": "[resourceId(variables('const_currentSubscription'), if(equals(parameters('ohsSSLConfigAccessOption'), variables('const_ohsSSLConfigAccessOptionKeyVaultStoredConfig')),parameters('keyVaultResourceGroup'),resourceGroup().name), 'Microsoft.KeyVault/vaults', if(equals(parameters('ohsSSLConfigAccessOption'), variables('const_ohsSSLConfigAccessOptionKeyVaultStoredConfig')),parameters('keyVaultName'),reference('ohsKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyVaultName.value))]" - }, - "secretName": "[if(equals(parameters('ohsSSLConfigAccessOption'), variables('const_ohsSSLConfigAccessOptionKeyVaultStoredConfig')),parameters('keyVaultSSLCertPasswordSecretName'),reference('ohsKeyVaultNestedTemplate', '${azure.apiVersion}').outputs.keyStorePwdSecretName.value)]" - } + "value": "[parameters('uploadedKeyStorePassword')]" }, "oracleVaultPswd": { "value": "[parameters('oracleVaultPswd')]" }, + "virtualNetworkNewOrExisting": { + "value": "[parameters('virtualNetworkNewOrExisting')]" + }, + "virtualNetworkResourceGroupName": { + "value": "[parameters('virtualNetworkResourceGroupName')]" + }, "virtualNetworkName": { - "value": "[reference(variables('clusterTemplateRef'),'${azure.apiVersion}').outputs.virtualNetworkName.value]" + "value": "[reference(variables('ref_clusterTemplate'),'${azure.apiVersionForDeployment}').outputs.virtualNetworkName.value]" }, - "vmSizeSelect": { - "value": "[parameters('vmSizeSelect')]" + "vmSize": { + "value": "[parameters('vmSize')]" }, "adminRestMgmtURL": { - "value": "[reference(variables('clusterTemplateRef'),'${azure.apiVersion}').outputs.adminRestMgmtURL.value]" + "value": "[reference(variables('ref_clusterTemplate'),'${azure.apiVersionForDeployment}').outputs.adminRestMgmtURL.value]" }, "wlsPassword": { "value": "[parameters('wlsPassword')]" @@ -1666,14 +1231,14 @@ "value": "[parameters('wlsUserName')]" }, "keyType": { - "value": "[if(equals(parameters('ohsSSLConfigAccessOption'), variables('const_ohsSSLConfigAccessOptionKeyVaultStoredConfig')),parameters('keyType'),parameters('uploadedKeyStoreType'))]" + "value": "[parameters('uploadedKeyStoreType')]" } } } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "dnszonesLinkedTemplate", "condition": "[parameters('enableCustomDNS')]", "dependsOn": [ @@ -1692,6 +1257,9 @@ "_artifactsLocationSasToken": { "value": "[parameters('_artifactsLocationSasToken')]" }, + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" + }, "dnszonesARecordSetNames": { "value": "[if(parameters('enableOHS'), createArray(parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneLoadBalancerLabel')), createArray(parameters('dnszoneAdminConsoleLabel')))]" }, @@ -1701,9 +1269,6 @@ "hasDNSZones": { "value": "[parameters('hasDNSZones')]" }, - "identity": { - "value": "[parameters('dnszoneIdentity')]" - }, "location": { "value": "[parameters('location')]" }, @@ -1711,27 +1276,98 @@ "value": "[parameters('dnszoneResourceGroup')]" }, "targetResources": { - "value": "[if(parameters('enableOHS'), createArray(reference(variables('clusterTemplateRef'), '${azure.apiVersion}').outputs._adminPublicIPId.value, reference('ohsLinkedTemplate', '${azure.apiVersion}').outputs._ohsPublicIP.value), createArray(reference(variables('clusterTemplateRef'), '${azure.apiVersion}').outputs._adminPublicIPId.value))]" + "value": "[if(parameters('enableOHS'), createArray(reference(variables('ref_clusterTemplate'), '${azure.apiVersionForDeployment}').outputs._adminPublicIPId.value, reference('ohsLinkedTemplate', '${azure.apiVersionForDeployment}').outputs._ohsPublicIP.value), createArray(reference(variables('ref_clusterTemplate'), '${azure.apiVersionForDeployment}').outputs._adminPublicIPId.value))]" } } - } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "[variables('name_uamiForPostDeploymentScript')]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'existing')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', variables('ref_clusterTemplate'))]", + "[resourceId('Microsoft.Resources/deployments', 'dbLinkedTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'coherenceTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'coherenceTemplateWithCustomSSL')]", + "[resourceId('Microsoft.Resources/deployments', 'ohsLinkedTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'dnszonesLinkedTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'networkSecurityLinkedTemplate')]" + ], + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_postDeploymentUAMIRolesTemplate')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "postDeplyment", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'existing')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', variables('ref_clusterTemplate'))]", + "[resourceId('Microsoft.Resources/deployments', 'dbLinkedTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'coherenceTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'coherenceTemplateWithCustomSSL')]", + "[resourceId('Microsoft.Resources/deployments', 'ohsLinkedTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'dnszonesLinkedTemplate')]", + "[resourceId('Microsoft.Resources/deployments', 'networkSecurityLinkedTemplate')]", + "[resourceId('Microsoft.Resources/deployments', variables('name_uamiForPostDeploymentScript'))]" + ], + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_postDeploymentTemplate')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "_globalResourceNameSuffix": { + "value": "[variables('const_globalResourceNameSuffix')]" + }, + "const_guidTag":{ + "value": "[variables('const_guidTag')]" + }, + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + }, + "userAssignedIdentityResourceId":{ + "value": "[reference(variables('name_uamiForPostDeploymentScript'),'${azure.apiVersionForDeployment}').outputs.uamidForPostDeployment.value]" + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${dynamic.end}", "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', variables('clusterTemplateRef'))]", - "[resourceId('Microsoft.Resources/deployments', 'aadLinkedTemplate')]", + "[resourceId('Microsoft.Resources/deployments', variables('ref_clusterTemplate'))]", "[resourceId('Microsoft.Resources/deployments', 'dbLinkedTemplate')]", - "[resourceId('Microsoft.Resources/deployments', 'elkLinkedTemplate')]", "[resourceId('Microsoft.Resources/deployments', 'coherenceTemplate')]", "[resourceId('Microsoft.Resources/deployments', 'coherenceTemplateWithCustomSSL')]", "[resourceId('Microsoft.Resources/deployments', 'ohsLinkedTemplate')]", "[resourceId('Microsoft.Resources/deployments', 'dnszonesLinkedTemplate')]", "[resourceId('Microsoft.Resources/deployments', 'networkSecurityLinkedTemplate')]", - "[resourceId('Microsoft.Resources/deployments', 'keyVaultNestedTemplate')]" + "[resourceId('Microsoft.Resources/deployments', variables('name_uamiForPostDeploymentScript'))]", + "[resourceId('Microsoft.Resources/deployments','postDeplyment')]" ], "properties": { "mode": "Incremental", @@ -1742,39 +1378,45 @@ } } } - ], "outputs": { + "adminVMName": { + "type": "string", + "value": "[variables('name_adminVM')]" + }, + "managedServerVMNamePrefix": { + "type": "string", + "value": "[concat(variables('name_managedVMNamePrefix'), 'VM')]" + }, "wlsDomainLocation": { "type": "string", - "value": "[reference(variables('clusterTemplateRef'),'${azure.apiVersion}').outputs.wlsDomainLocation.value]" + "value": "[reference(variables('ref_clusterTemplate'),'${azure.apiVersionForDeployment}').outputs.wlsDomainLocation.value]" }, "adminHostName": { "type": "string", - "value": "[reference(variables('clusterTemplateRef'),'${azure.apiVersion}').outputs.adminHostName.value]" + "value": "[reference(variables('ref_clusterTemplate'),'${azure.apiVersionForDeployment}').outputs.adminHostName.value]" }, "adminConsole": { "type": "string", - "value": "[if(parameters('enableCustomDNS'), format('http://{0}.{1}:7001/console',parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')),reference(variables('clusterTemplateRef'),'${azure.apiVersion}').outputs.adminConsole.value)]" + "value": "[if(parameters('enableCustomDNS'), uri(format('http://{0}.{1}:7001/console/',parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')), ''),reference(variables('ref_clusterTemplate'),'${azure.apiVersionForDeployment}').outputs.adminConsole.value)]" }, "adminSecuredConsole": { "type": "string", - "value": "[if(parameters('enableCustomDNS'), format('https://{0}.{1}:7002/console',parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')),reference(variables('clusterTemplateRef'),'${azure.apiVersion}').outputs.adminSecuredConsole.value)]" + "value": "[if(parameters('enableCustomDNS'), uri(format('https://{0}.{1}:7002/console',parameters('dnszoneAdminConsoleLabel'),parameters('dnszoneName')), ''),reference(variables('ref_clusterTemplate'),'${azure.apiVersionForDeployment}').outputs.adminSecuredConsole.value)]" }, - "logIndex": { + "ohsVMName": { "type": "string", - "condition": "[parameters('enableELK')]", - "value": "[if(parameters('enableELK'), reference('elkLinkedTemplate', '${azure.apiVersion}').outputs.logIndex.value, '')]" + "value": "[variables('name_ohsVMName')]" }, "ohsAccessURL": { "type": "string", "condition": "[parameters('enableOHS')]", - "value": "[if(parameters('enableCustomDNS'), format('http://{0}.{1}:{2}',parameters('dnszoneLoadBalancerLabel'),parameters('dnszoneName'), parameters('ohshttpPort')),reference('ohsLinkedTemplate', '${azure.apiVersion}').outputs.ohsAccessURL.value)]" + "value": "[if(parameters('enableCustomDNS'), uri(format('http://{0}.{1}:{2}',parameters('dnszoneLoadBalancerLabel'),parameters('dnszoneName'), parameters('ohshttpPort')),''),reference('ohsLinkedTemplate', '${azure.apiVersionForDeployment}').outputs.ohsAccessURL.value)]" }, "ohsSecureAccessURL": { "type": "string", "condition": "[parameters('enableOHS')]", - "value": "[if(parameters('enableCustomDNS'), format('https://{0}.{1}:{2}',parameters('dnszoneLoadBalancerLabel'),parameters('dnszoneName'),parameters('ohshttpsPort')), reference('ohsLinkedTemplate', '${azure.apiVersion}').outputs.ohsSecureAccessURL.value)]" + "value": "[if(parameters('enableCustomDNS'), uri(format('https://{0}.{1}:{2}',parameters('dnszoneLoadBalancerLabel'),parameters('dnszoneName'),parameters('ohshttpsPort')),''), reference('ohsLinkedTemplate', '${azure.apiVersionForDeployment}').outputs.ohsSecureAccessURL.value)]" } } -} +} \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_appendUserManagedIdentity.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_appendUserManagedIdentity.json new file mode 100644 index 000000000..ba47748a4 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_appendUserManagedIdentity.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "vmName": { + "type": "string" + }, + "existingIdentities": { + "type": "object" + }, + "newIdentities": { + "type": "object" + }, + "location": { + "type": "string" + } + }, + "resources": [ + { + "apiVersion": "${azure.apiVersionForVirtualMachines}", + "type": "Microsoft.Compute/virtualMachines", + "name": "[parameters('vmName')]", + "location": "[parameters('location')]", + "identity": { + "type": "userAssigned", + "userAssignedIdentities": "[union(parameters('existingIdentities'),parameters('newIdentities'))]" + } + } + ] +} \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_dbTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_dbTemplate.json new file mode 100644 index 000000000..0bd5719af --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_dbTemplate.json @@ -0,0 +1,244 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." + } + }, + "_artifactsLocationDbTemplate": { + "defaultValue": "[if(contains(parameters('_artifactsLocation'), 'githubusercontent'), parameters('_artifactsLocation'), deployment().properties.templateLink.uri)]", + "type": "string", + "metadata": { + "description": "If we are deploying from the command line, use the passed in _artifactsLocation, otherwise use the default." + } + }, + "_artifactsLocationSasToken": { + "defaultValue": "", + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." + } + }, + "adminVMName": { + "defaultValue": "adminVM", + "type": "string", + "metadata": { + "description": "Admin Server hosting VM name." + } + }, + "databaseType": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "One of the supported database types" + } + }, + "dbGlobalTranPro": { + "defaultValue": "OnePhaseCommit", + "type": "string", + "metadata": { + "description": "Determines the transaction protocol (global transaction processing behavior) for the data source." + } + }, + "dbPassword": { + "defaultValue": "[newGuid()]", + "type": "securestring", + "metadata": { + "description": "Password for Database" + } + }, + "dbUser": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Userid of Database" + } + }, + "dsConnectionURL": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "JDBC Connection String" + } + }, + "enablePswlessConnection": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "True to enable passwordless connection." + } + }, + "jdbcDataSourceName": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "JNDI Name for JDBC Datasource" + } + }, + "location": { + "type": "string", + "metadata": { + "description": "Location for all resources." + } + }, + "wlsUserName": { + "defaultValue": "weblogic", + "type": "string", + "metadata": { + "description": "Username for your Weblogic domain name" + } + }, + "wlsPassword": { + "type": "securestring", + "metadata": { + "description": "Password for your Weblogic domain name" + } + } + }, + "variables": { + "const_wlsAdminPort": "7005", + "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", + "name_scriptFilePrefix": "datasourceConfig-", + "name_scriptFileSuffix-sqlserver": "sqlserver.sh", + "name_scriptFileSuffix-oracle": "oracle.sh", + "name_scriptFileSuffix-postgresql": "postgresql.sh", + "name_scriptFileSuffix-mysql": "mysql.sh" + }, + "resources": [ + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${dynamic.database.start}", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "apiVersion": "${azure.apiVersionForVirtualMachines}", + "type": "Microsoft.Compute/virtualMachines/extensions", + "name": "[concat(parameters('adminVMName'),'/newuserscript')]", + "location": "[parameters('location')]", + "properties": { + "publisher": "Microsoft.Azure.Extensions", + "type": "CustomScript", + "typeHandlerVersion": "2.0", + "autoUpgradeMinorVersion": true, + "settings": { + "fileUris": [ + "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-sqlserver'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-oracle'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-postgresql'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-mysql'), parameters('_artifactsLocationSasToken')))]" + ] + }, + "protectedSettings": { + "commandToExecute": "[concat('sh',' ',variables('name_scriptFilePrefix'),parameters('databaseType'),'.sh <<< \"',variables('const_wlsHome'),' ',parameters('adminVMName'),' ',variables('const_wlsAdminPort'),' ',parameters('wlsUserName'),' ',base64(parameters('wlsPassword')),' ',base64(parameters('jdbcDataSourceName')),' ',base64(parameters('dsConnectionURL')),' ',parameters('dbUser'),' ',base64(parameters('dbPassword')),' ',parameters('dbGlobalTranPro'),' ', parameters('enablePswlessConnection'),'\"')]" + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${dynamic.database.end}", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${database.oracle}", + "condition": "[if(contains(parameters('databaseType'), 'oracle'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${database.postgresql}", + "condition": "[if(contains(parameters('databaseType'), 'postgresql'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${database.mysql}", + "condition": "[if(contains(parameters('databaseType'), 'mysql'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${database.sqlserver}", + "condition": "[if(contains(parameters('databaseType'), 'sqlserver'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + } + ], + "outputs": { + "artifactsLocationPassedIn": { + "type": "string", + "value": "[parameters('_artifactsLocation')]" + } + } +} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_dnszones/_uamiAndRoleAssignment.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_dnszones/_uamiAndRoleAssignment.json new file mode 100644 index 000000000..c8d6c3eeb --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_dnszones/_uamiAndRoleAssignment.json @@ -0,0 +1,89 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string" + }, + "uamiName": { + "type": "string" + } + }, + "functions": [], + "variables": { + "const_roleDefinitionIdOfContributor": "b24988ac-6180-42a0-ab88-20f7382dd24c", + "name_deploymentScriptContributorRoleAssignmentName": "[guid(format('{0}{1}Deployment Script', resourceGroup().id, parameters('uamiName')))]" + }, + "resources": [ + { + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "${azure.apiVersionForIdentity}", + "name": "[parameters('uamiName')]", + "location": "[parameters('location')]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "[variables('name_deploymentScriptContributorRoleAssignmentName')]", + "subscriptionId": "[subscription().subscriptionId]", + "location": "[parameters('location')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "roleDefinition": { + "value": "[variables('const_roleDefinitionIdOfContributor')]" + }, + "principalId": { + "value": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('uamiName'))).principalId]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "roleDefinition": { + "type": "string", + "defaultValue": "" + }, + "principalId": { + "type": "string", + "defaultValue": "" + } + }, + "functions": [], + "variables": { + "name_roleAssignmentName": "[guid(format('{0}{1}Role assignment in subscription scope', subscription().id, parameters('principalId')))]" + }, + "resources": [ + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "${azure.apiVersionForRoleAssignment}", + "name": "[variables('name_roleAssignmentName')]", + "properties": { + "description": "Assign subscription scope role to User Assigned Managed Identity ", + "principalId": "[parameters('principalId')]", + "principalType": "ServicePrincipal", + "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinition'))]" + } + } + ], + "outputs": { + "roleId": { + "type": "string", + "value": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinition'))]" + } + } + } + } + } + ], + "outputs": { + "uamiIdForDeploymentScript": { + "type": "string", + "value": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('uamiName'))]" + } + } + } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_dnszones/_updateDNSZonesTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_dnszones/_updateDNSZonesTemplate.json index 74207d21a..b03e9d1c1 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_dnszones/_updateDNSZonesTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_dnszones/_updateDNSZonesTemplate.json @@ -22,6 +22,12 @@ "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." } }, + "_globalResourceNameSuffix": { + "type": "string", + "metadata": { + "description": "A suffix to be appended to all resources created by this template." + } + }, "dnszonesARecordSetNames": { "type": "array", "metadata": { @@ -46,12 +52,6 @@ "description": "Azure DNS Zone name." } }, - "identity": { - "type": "Object", - "metadata": { - "description": "Managed identity to be used for the deployment script. Currently, only user-assigned MSI is supported." - } - }, "location": { "type": "string", "metadata": { @@ -105,21 +105,100 @@ } ], "variables": { - "name_scriptDNSConfiguration": "updateDNSZones.sh" + "name_deploymentScriptUserDefinedManagedIdentity": "wls-vm-dns-user-defined-managed-itentity", + "name_scriptDNSConfiguration": "updateDNSZones.sh", + "name_templateUAMIDeployment": "_uamiAndRoleAssignment.json" }, "resources": [ + { + "type": "Microsoft.Resources/deployments", + "name": "uamiDeployment", + "apiVersion": "${azure.apiVersionForDeployment}", + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/_dnszones/', variables('name_templateUAMIDeployment')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "uamiName": { + "value": "[variables('name_deploymentScriptUserDefinedManagedIdentity')]" + } + } + } + }, { "type": "Microsoft.Resources/deploymentScripts", "apiVersion": "${azure.apiVersionForDeploymentScript}", - "name": "script-createDNSRecords", + "name": "[concat('script-create-dns-records-', parameters('_globalResourceNameSuffix'))]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'uamiDeployment')]" + ], "location": "[parameters('location')]", - "identity": "[parameters('identity')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('name_deploymentScriptUserDefinedManagedIdentity'))]": {} + } + }, "kind": "AzureCLI", "properties": { "forceUpdateTag": "[parameters('utcValue')]", - "AzCliVersion": "2.15.0", + "AzCliVersion": "${azure.cli.version}", "timeout": "PT30M", - "arguments": "[format('{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10}', parameters('resourceGroup'), parameters('dnszoneName'), array.join(parameters('dnszonesARecordSetNames')),array.join(parameters('targetResources')), length(parameters('dnszonesARecordSetNames')), length(parameters('targetResources')), parameters('ttl'), array.join(parameters('dnszonesCNAMERecordSetNames')),array.join(parameters('dnszonesCNAMEAlias')),length(parameters('dnszonesCNAMERecordSetNames')), length(parameters('dnszonesCNAMEAlias')))]", + "environmentVariables": [ + { + "name": "DNS_CNAME_ALIAS", + "value": "[array.join(parameters('dnszonesCNAMEAlias'))]" + }, + { + "name": "DNS_CNAME_ALIAS_LENGTH", + "value": "[length(parameters('dnszonesCNAMEAlias'))]" + }, + { + "name": "DNS_CNAME_RECORDSET_LENGTH", + "value": "[length(parameters('dnszonesCNAMERecordSetNames'))]" + }, + { + "name": "DNS_CNAME_RECORDSET_NAMES", + "value": "[array.join(parameters('dnszonesCNAMERecordSetNames'))]" + }, + { + "name": "DNS_RECORDSET_NAMES", + "value": "[array.join(parameters('dnszonesARecordSetNames'))]" + }, + { + "name": "DNS_RECORD_NAMES_LENGTH", + "value": "[length(parameters('dnszonesARecordSetNames'))]" + }, + { + "name": "DNS_TARGET_RESOURCES_LENGTH", + "value": "[length(parameters('targetResources'))]" + }, + { + "name": "DNS_TARGET_RESOURCES", + "value": "[array.join(parameters('targetResources'))]" + }, + { + "name": "DNS_RECORD_TTL", + "value": "[parameters('ttl')]" + }, + { + "name": "DNS_ZONE_NAME", + "value": "[parameters('dnszoneName')]" + }, + { + "name": "MANAGED_IDENTITY_ID", + "value": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('name_deploymentScriptUserDefinedManagedIdentity'))]" + }, + { + "name": "RESOURCE_GROUP_NAME", + "value": "[parameters('resourceGroup')]" + } + ], "primaryScriptUri": "[uri(parameters('_artifactsLocationDNSZonesTemplate'), concat('../../scripts/', variables('name_scriptDNSConfiguration'), parameters('_artifactsLocationSasToken')))]", "cleanupPreference": "OnSuccess", "retentionInterval": "P1D" diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_installJdbcLibsTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_installJdbcLibsTemplate.json new file mode 100644 index 000000000..68a2cfc29 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_installJdbcLibsTemplate.json @@ -0,0 +1,147 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." + } + }, + "_artifactsLocationInstallJdbcLibsTemplate": { + "defaultValue": "[if(contains(parameters('_artifactsLocation'), 'githubusercontent'), parameters('_artifactsLocation'), deployment().properties.templateLink.uri)]", + "type": "string", + "metadata": { + "description": "If we are deploying from the command line, use the passed in _artifactsLocation, otherwise use the default." + } + }, + "_artifactsLocationSasToken": { + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." + }, + "defaultValue": "" + }, + "adminVMName": { + "type": "string", + "defaultValue": "adminVM", + "metadata": { + "description": "Admin Server hosting VM name." + } + }, + "databaseType": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "One of the supported database types" + } + }, + "enablePswlessConnection": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "True to enable passwordless connection." + } + }, + "location": { + "type": "string", + "metadata": { + "description": "Location for all resources." + } + }, + "managedServerPrefix": { + "type": "string", + "defaultValue": "msp", + "metadata": { + "description": "Provide managed server prefix name" + } + }, + "managedVMNamePrefix": { + "type": "string", + "metadata": { + "description": "Managed Server hosting VM name prefix." + } + }, + "numberOfManagedApplicationInstances": { + "type": "int", + "defaultValue": 2, + "minValue": 1, + "maxValue": 20, + "metadata": { + "description": "Number of VMs that have been deployed to host managed application server." + } + }, + "wlsDomainName": { + "type": "string", + "defaultValue": "wlsd", + "metadata": { + "description": "Provide Weblogic domain name" + } + }, + "wlsPassword": { + "type": "securestring", + "metadata": { + "description": "Password for your Weblogic domain name" + } + }, + "wlsUserName": { + "type": "string", + "metadata": { + "description": "Username for your Weblogic domain name" + } + } + }, + "variables": { + "const_managedVMPrefix": "[concat(parameters('managedVMNamePrefix'),'VM')]", + "const_wlsAdminPort": "7005", + "const_wlsDomainPath": "[concat('/u01/domains/', parameters('wlsDomainName'))]", + "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", + "name_scriptInstallJdbcLibs": "installJdbcDrivers.sh" + }, + "resources": [ + { + "apiVersion": "${azure.apiVersionForVirtualMachines}", + "type": "Microsoft.Compute/virtualMachines/extensions", + "name": "[concat(variables('const_managedVMPrefix'), copyIndex(1),'/newuserscript')]", + "location": "[parameters('location')]", + "copy": { + "name": "appVirtualMachineExtensionLoop", + "count": "[parameters('numberOfManagedApplicationInstances')]" + }, + "properties": { + "publisher": "Microsoft.Azure.Extensions", + "type": "CustomScript", + "typeHandlerVersion": "2.0", + "autoUpgradeMinorVersion": true, + "settings": { + "fileUris": [ + "[uri(parameters('_artifactsLocationInstallJdbcLibsTemplate'), concat('../scripts/', variables('name_scriptInstallJdbcLibs'), parameters('_artifactsLocationSasToken')))]" + ] + }, + "protectedSettings": { + "commandToExecute": "[concat('sh',' ',variables('name_scriptInstallJdbcLibs'),' <<< \"',variables('const_wlsHome'),' ',variables('const_wlsDomainPath'),' ',parameters('managedServerPrefix'), copyIndex(1), ' ', parameters('adminVMName'), ' ',variables('const_wlsAdminPort'),' ',parameters('wlsUserName'),' ',base64(parameters('wlsPassword')),' ',parameters('databaseType'),' ',parameters('enablePswlessConnection'), '\"')]" + } + } + }, + { + "apiVersion": "${azure.apiVersionForVirtualMachines}", + "type": "Microsoft.Compute/virtualMachines/extensions", + "name": "[concat(parameters('adminVMName'), '/newuserscript')]", + "location": "[parameters('location')]", + "properties": { + "publisher": "Microsoft.Azure.Extensions", + "type": "CustomScript", + "typeHandlerVersion": "2.0", + "autoUpgradeMinorVersion": true, + "settings": { + "fileUris": [ + "[uri(parameters('_artifactsLocationInstallJdbcLibsTemplate'), concat('../scripts/', variables('name_scriptInstallJdbcLibs'), parameters('_artifactsLocationSasToken')))]" + ] + }, + "protectedSettings": { + "commandToExecute": "[concat('sh',' ',variables('name_scriptInstallJdbcLibs'),' <<< \"',variables('const_wlsHome'),' ',variables('const_wlsDomainPath'),' ','admin', ' ', parameters('adminVMName'), ' ',variables('const_wlsAdminPort'),' ',parameters('wlsUserName'),' ',base64(parameters('wlsPassword')),' ',parameters('databaseType'),' ',parameters('enablePswlessConnection'), '\"')]" + } + } + } + ] +} \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_ohsKeyVaultNestedTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_ohsKeyVaultNestedTemplate.json deleted file mode 100644 index 5d48e9250..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_ohsKeyVaultNestedTemplate.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "uploadedKeyStoreData": { - "type": "string", - "metadata": { - "description": "Custom Identity KeyStore Data" - } - }, - "uploadedKeyStorePassword": { - "type": "string", - "metadata": { - "description": "Custom Identity KeyStore Passphrase" - } - }, - "enabledForTemplateDeployment": { - "type": "bool", - "metadata": { - "description": "Property to specify whether Azure Resource Manager is permitted to retrieve secrets from the key vault." - }, - "defaultValue": true - }, - "location": { - "type": "string", - "metadata": { - "description": "The supported Azure location where the key vault should be created." - } - }, - "sku": { - "type": "string", - "metadata": { - "description": "Price tier for Key Vault." - }, - "defaultValue": "Standard" - }, - "keyVaultName": { - "type": "string", - "metadata": { - "description": "Name of the Key Vault" - }, - "defaultValue": "GEN_UNIQUE" - } - }, - "variables": { - "name_keyStoreDataSecretName": "ohsSSLKeyStoreData", - "name_keyStorePwdSecretName": "ohsSSLKeyStorePassword" - }, - "resources": [ - { - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[parameters('keyVaultName')]", - "location": "[parameters('location')]", - "type": "Microsoft.KeyVault/vaults", - "properties": { - "enabledForTemplateDeployment": "[parameters('enabledForTemplateDeployment')]", - "sku": { - "name": "[parameters('sku')]", - "family": "A" - }, - "accessPolicies": [], - "tenantId": "[subscription().tenantId]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(parameters('keyVaultName'), '/', variables('name_keyStoreDataSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedKeyStoreData')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(parameters('keyVaultName'), '/', variables('name_keyStorePwdSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedKeyStorePassword')]" - } - } - ], - "outputs": { - "keyVaultName": { - "type": "string", - "value": "[parameters('keyVaultName')]" - }, - "keyStoreDataSecretName": { - "type": "string", - "value": "[variables('name_keyStoreDataSecretName')]" - }, - "keyStorePwdSecretName": { - "type": "string", - "value": "[variables('name_keyStorePwdSecretName')]" - } - } -} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_pswlessDbTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_pswlessDbTemplate.json new file mode 100644 index 000000000..f5d330105 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_pswlessDbTemplate.json @@ -0,0 +1,322 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." + } + }, + "_artifactsLocationSasToken": { + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." + }, + "defaultValue": "" + }, + "adminVMName": { + "type": "string", + "defaultValue": "adminVM", + "metadata": { + "description": "Admin Server hosting VM name." + } + }, + "databaseType": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "One of the supported database types" + } + }, + "dbGlobalTranPro": { + "defaultValue": "OnePhaseCommit", + "type": "string", + "metadata": { + "description": "Determines the transaction protocol (global transaction processing behavior) for the data source." + } + }, + "dbIdentity": { + "defaultValue": {}, + "type": "object", + "metadata": { + "description": "Managed identity that has access to the data source." + } + }, + "dbUser": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Userid of Database" + } + }, + "dsConnectionURL": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "JDBC Connection String" + } + }, + "jdbcDataSourceName": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "JNDI Name for JDBC Datasource" + } + }, + "location": { + "type": "string", + "metadata": { + "description": "Location for all resources." + } + }, + "managedServerPrefix": { + "type": "string", + "defaultValue": "msp", + "metadata": { + "description": "Provide managed server prefix name" + } + }, + "managedVMNamePrefix": { + "type": "string", + "metadata": { + "description": "Provide managed VM name prefix" + } + }, + "numberOfManagedApplicationInstances": { + "type": "int", + "defaultValue": 2, + "minValue": 1, + "maxValue": 20, + "metadata": { + "description": "Number of VMs that have been deployed to host managed application server." + } + }, + "wlsDomainName": { + "type": "string", + "defaultValue": "wlsd", + "metadata": { + "description": "Provide Weblogic domain name" + } + }, + "wlsPassword": { + "type": "securestring", + "metadata": { + "description": "Password for your Weblogic domain name" + } + }, + "wlsUserName": { + "type": "string", + "metadata": { + "description": "Username for your Weblogic domain name" + } + } + }, + "variables": { + "const_connectionString": "[if(and(equals(parameters('databaseType'),'sqlserver'), equals(last(parameters('dsConnectionURL')),';')), take(parameters('dsConnectionURL'), add(length(parameters('dsConnectionURL')),-1)),parameters('dsConnectionURL'))]", + "const_identityAPIVersion": "${azure.apiVersionForIdentity}", + "const_managedVMPrefix": "[concat(parameters('managedVMNamePrefix'), 'VM')]", + "const_msiDefaultUser": "msiUser", + "name_appendIdentityTemplate": "_appendUserManagedIdentity.json", + "name_installJdbcLibsTemplate": "_installJdbcLibsTemplate.json", + "name_dbTemplate": "_dbTemplate.json", + "array_azureJdbcPlugins": { + "mysql": "defaultAuthenticationPlugin=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin&authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin", + "postgresql": "authenticationPluginClassName=com.azure.identity.extensions.jdbc.postgresql.AzurePostgresqlAuthenticationPlugin", + "sqlserver": "authentication=ActiveDirectoryMSI" + }, + "array_urlJoiner": { + "mysql": "[if(contains(variables('const_connectionString'), '?'), '&', '?')]", + "postgresql": "[if(contains(variables('const_connectionString'), '?'), '&', '?')]", + "sqlserver": ";" + }, + "array_paramJoiner": { + "mysql": "&", + "postgresql": "&", + "sqlserver": ";" + }, + "array_msiClientId": { + "mysql": "azure.clientId", + "postgresql": "azure.clientId", + "sqlserver": "msiClientId" + }, + "obj_dbIdentity": { + "[items(parameters('dbIdentity').userAssignedIdentities)[0].key]": {} + }, + "obj_empty": {} + }, + "resources": [ + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${dynamic.pswless.database.start}", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "[concat('assignDbIdentityTo',variables('const_managedVMPrefix'), copyIndex(1))]", + "copy": { + "name": "virtualMachineIdentityLoop", + "count": "[parameters('numberOfManagedApplicationInstances')]" + }, + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_appendIdentityTemplate')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "vmName": { + "value": "[concat(variables('const_managedVMPrefix'), copyIndex(1))]" + }, + "newIdentities": { + "value": "[variables('obj_dbIdentity')]" + }, + "existingIdentities": { + "value": "[if(equals(reference(resourceId('Microsoft.Compute/virtualMachines',concat(variables('const_managedVMPrefix'), copyIndex(1))), '${azure.apiVersionForVirtualMachines}', 'Full').identity.type,'UserAssigned'),reference(resourceId('Microsoft.Compute/virtualMachines',concat(variables('const_managedVMPrefix'), copyIndex(1))), '${azure.apiVersionForVirtualMachines}', 'Full').identity.userAssignedIdentities, variables('obj_empty'))]" + }, + "location": { + "value": "[parameters('location')]" + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "installJdbcLibsTemplate", + "condition": "[or(equals(parameters('databaseType'),'mysql'), equals(parameters('databaseType'),'postgresql'))]", + "dependsOn": [ + "virtualMachineIdentityLoop" + ], + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_installJdbcLibsTemplate')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + }, + "adminVMName": { + "value": "[parameters('adminVMName')]" + }, + "databaseType": { + "value": "[parameters('databaseType')]" + }, + "enablePswlessConnection": { + "value": true + }, + "location": { + "value": "[parameters('location')]" + }, + "managedServerPrefix": { + "value": "[parameters('managedServerPrefix')]" + }, + "managedVMNamePrefix": { + "value": "[parameters('managedVMNamePrefix')]" + }, + "numberOfManagedApplicationInstances": { + "value": "[parameters('numberOfManagedApplicationInstances')]" + }, + "wlsDomainName": { + "value": "[parameters('wlsDomainName')]" + }, + "wlsPassword": { + "value": "[parameters('wlsPassword')]" + }, + "wlsUserName": { + "value": "[parameters('wlsUserName')]" + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "passwordlessDatasourceDeployment", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'installJdbcLibsTemplate')]" + ], + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_dbTemplate')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + }, + "adminVMName": { + "value": "[parameters('adminVMName')]" + }, + "databaseType": { + "value": "[parameters('databaseType')]" + }, + "dbGlobalTranPro": { + "value": "[parameters('dbGlobalTranPro')]" + }, + "dsConnectionURL": { + "value": "[uri(format('{0}{4}{1}{5}{2}={3}', variables('const_connectionString'), variables('array_azureJdbcPlugins')[parameters('databaseType')], variables('array_msiClientId')[parameters('databaseType')], reference(items(parameters('dbIdentity').userAssignedIdentities)[0].key,variables('const_identityAPIVersion'), 'full').properties.clientId, variables('array_urlJoiner')[parameters('databaseType')], variables('array_paramJoiner')[parameters('databaseType')]), '')]" + }, + "dbUser": { + "value": "[if(equals(parameters('databaseType'), 'sqlserver'), variables('const_msiDefaultUser'), parameters('dbUser'))]" + }, + "enablePswlessConnection": { + "value": true + }, + "jdbcDataSourceName": { + "value": "[parameters('jdbcDataSourceName')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "wlsPassword": { + "value": "[parameters('wlsPassword')]" + }, + "wlsUserName": { + "value": "[parameters('wlsUserName')]" + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${dynamic.pswless.database.end}", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'passwordlessDatasourceDeployment')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + } + ], + "outputs": { + "artifactsLocationPassedIn": { + "type": "string", + "value": "[parameters('_artifactsLocation')]" + } + } +} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_sslKeyVaultNestedTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_sslKeyVaultNestedTemplate.json deleted file mode 100644 index 303d5c417..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/_sslKeyVaultNestedTemplate.json +++ /dev/null @@ -1,197 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "uploadedCustomIdentityKeyStoreData": { - "type": "securestring", - "metadata": { - "description": "Custom Identity KeyStore Data" - }, - "defaultValue": "[newGuid()]" - }, - "uploadedCustomIdentityKeyStorePassphrase": { - "type": "securestring", - "metadata": { - "description": "Custom Identity KeyStore Passphrase" - } - }, - "uploadedCustomTrustKeyStoreData": { - "type": "securestring", - "metadata": { - "description": "Custom Trust KeyStore Data" - } - }, - "uploadedCustomTrustKeyStorePassPhrase": { - "type": "securestring", - "metadata": { - "description": "Custom Trust KeyStore PassPhrase" - } - }, - "uploadedPrivateKeyAlias": { - "type": "string", - "metadata": { - "description": "Alias of the private key" - } - }, - "uploadedPrivateKeyPassPhrase": { - "type": "securestring", - "metadata": { - "description": "Password of the private key" - } - }, - "enabledForTemplateDeployment": { - "type": "bool", - "metadata": { - "description": "Property to specify whether Azure Resource Manager is permitted to retrieve secrets from the key vault." - }, - "defaultValue": true - }, - "location": { - "type": "string", - "metadata": { - "description": "The supported Azure location where the key vault should be created." - } - }, - "sku": { - "type": "string", - "metadata": { - "description": "Price tier for Key Vault." - }, - "defaultValue": "Standard" - }, - "keyVaultName": { - "type": "string", - "metadata": { - "description": "Name of the Key Vault" - }, - "defaultValue": "GEN_UNIQUE" - } - }, - "variables": { - "name_customIdentityKeyStoreDataSecretName": "customIdentityKeyStoreData", - "name_customIdentityKeyStorePassPhraseSecretName": "customIdentityKeyStorePassPhrase", - "name_customTrustKeyStoreDataSecretName": "customTrustKeyStoreData", - "name_customTrustKeyStorePassPhraseSecretName": "customTrustKeyStorePassPhrase", - "name_privateKeyAliasSecretName": "privateKeyAlias", - "name_privateKeyPassPhraseSecretName": "privateKeyPassPhrase" - }, - "resources": [ - { - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[parameters('keyVaultName')]", - "location": "[parameters('location')]", - "type": "Microsoft.KeyVault/vaults", - "properties": { - "enabledForTemplateDeployment": "[parameters('enabledForTemplateDeployment')]", - "sku": { - "name": "[parameters('sku')]", - "family": "A" - }, - "accessPolicies": [], - "tenantId": "[subscription().tenantId]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(parameters('keyVaultName'), '/', variables('name_customIdentityKeyStoreDataSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedCustomIdentityKeyStoreData')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(parameters('keyVaultName'), '/', variables('name_customIdentityKeyStorePassPhraseSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedCustomIdentityKeyStorePassphrase')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(parameters('keyVaultName'), '/', variables('name_customTrustKeyStoreDataSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedCustomTrustKeyStoreData')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(parameters('keyVaultName'), '/', variables('name_customTrustKeyStorePassPhraseSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedCustomTrustKeyStorePassPhrase')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(parameters('keyVaultName'), '/', variables('name_privateKeyAliasSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedPrivateKeyAlias')]" - } - }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "${azure.apiVersionForKeyVault}", - "name": "[concat(parameters('keyVaultName'), '/', variables('name_privateKeyPassPhraseSecretName'))]", - "location": "[parameters('location')]", - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]" - ], - "properties": { - "value": "[parameters('uploadedPrivateKeyPassPhrase')]" - } - } - ], - "outputs": { - "keyVaultName": { - "type": "string", - "value": "[parameters('keyVaultName')]" - }, - "customIdentityKeyStoreDataSecretName": { - "type": "string", - "value": "[variables('name_customIdentityKeyStoreDataSecretName')]" - }, - "customIdentityKeyStorePassPhraseSecretName": { - "type": "string", - "value": "[variables('name_customIdentityKeyStorePassPhraseSecretName')]" - }, - "customTrustKeyStoretDataSecretName": { - "type": "string", - "value": "[variables('name_customTrustKeyStoreDataSecretName')]" - }, - "customTrustKeyStorePassPhraseSecretName": { - "type": "string", - "value": "[variables('name_customTrustKeyStorePassPhraseSecretName')]" - }, - "privateKeyAliasSecretName": { - "type": "string", - "value": "[variables('name_privateKeyAliasSecretName')]" - }, - "privateKeyPassPhraseSecretName": { - "type": "string", - "value": "[variables('name_privateKeyPassPhraseSecretName')]" - } - } -} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/aadNestedTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/aadNestedTemplate.json deleted file mode 100644 index e2f19cee8..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/aadNestedTemplate.json +++ /dev/null @@ -1,251 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "_artifactsLocation": { - "type": "string", - "metadata": { - "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." - } - }, - "_artifactsLocationAADTemplate": { - "defaultValue": "[if(contains(parameters('_artifactsLocation'), 'githubusercontent'), parameters('_artifactsLocation'), deployment().properties.templateLink.uri)]", - "type": "string", - "metadata": { - "description": "If we are deploying from the command line, use the passed in _artifactsLocation, otherwise use the default." - } - }, - "_artifactsLocationSasToken": { - "defaultValue": "", - "type": "securestring", - "metadata": { - "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." - } - }, - "aadsPortNumber": { - "defaultValue": "636", - "type": "string", - "metadata": { - "description": "Accessible port of the LDAP server." - } - }, - "aadsPublicIP": { - "defaultValue": "The LDAP server public IP address", - "type": "string" - }, - "aadsServerHost": { - "defaultValue": "", - "type": "string", - "metadata": { - "description": "The LDAP server host." - } - }, - "adminVMName": { - "type": "string", - "defaultValue": "adminVM", - "metadata": { - "description": "Admin Server hosting VM name." - } - }, - "dynamicClusterSize": { - "type": "int", - "defaultValue": 1, - "minValue": 1, - "maxValue": 100, - "metadata": { - "description": "Number of VMs hosting managed servers that have been deployed." - } - }, - "location": { - "type": "string", - "metadata": { - "description": "Location for all resources." - } - }, - "managedServerPrefix": { - "type": "string", - "defaultValue": "msp", - "metadata": { - "description": "Provide managed server prefix name" - } - }, - "wlsDomainName": { - "defaultValue": "wlsd", - "type": "string", - "metadata": { - "description": "Provide Weblogic domain name" - } - }, - "wlsLDAPGroupBaseDN": { - "defaultValue": "", - "type": "securestring", - "metadata": { - "description": "The base distinguished name (DN) of the tree in the LDAP directory that contains groups." - } - }, - "wlsLDAPPrincipal": { - "defaultValue": "", - "type": "securestring", - "metadata": { - "description": "The Distinguished Name (DN) of the LDAP user that WebLogic Server should use to connect to the LDAP server." - } - }, - "wlsLDAPPrincipalPassword": { - "defaultValue": "[newGuid()]", - "type": "securestring", - "metadata": { - "description": "The credential (usually a password) used to connect to the LDAP server." - } - }, - "wlsLDAPProviderName": { - "defaultValue": "AzureActiveDirectoryProvider", - "type": "string", - "metadata": { - "description": "The value used for creating authentication provider name of WebLogic Server." - } - }, - "wlsLDAPSSLCertificate": { - "defaultValue": "", - "type": "securestring", - "metadata": { - "description": "Client certificate that will be imported to trust store of SSL." - } - }, - "wlsLDAPUserBaseDN": { - "defaultValue": "", - "type": "securestring", - "metadata": { - "description": "The base distinguished name (DN) of the tree in the LDAP directory that contains users." - } - }, - "wlsPassword": { - "type": "securestring", - "metadata": { - "description": "Password for your Weblogic domain name" - } - }, - "wlsUserName": { - "defaultValue": "weblogic", - "type": "string", - "metadata": { - "description": "Username for your Weblogic domain name" - } - }, - "enableCustomSSL": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Boolean value indicating, if custom SSL is enabled or not" - } - }, - "keyVaultCustomTrustKeyStorePassPhrase": { - "type": "securestring", - "defaultValue": "", - "metadata": { - "description": "Weblogic Custom Trust Store Passphrase" - } - }, - "keyVaultCustomTrustKeyStoreType": { - "type": "string", - "defaultValue": "null", - "metadata": { - "description": "Weblogic Custom Trust Store Type (JKS or PKCS12)" - } - } - }, - "variables": { - "const_aadParameters": "[concat(parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('wlsDomainName'),' ',parameters('wlsLDAPProviderName'), ' ', parameters('aadsServerHost'), ' ', parameters('aadsPortNumber'), ' ', concat('\"',parameters('wlsLDAPPrincipal'),'\"'), ' ', parameters('wlsLDAPPrincipalPassword'), ' ', concat('\"',parameters('wlsLDAPUserBaseDN'),'\"'), ' ', concat('\"',parameters('wlsLDAPGroupBaseDN'),'\"'), ' ', variables('const_wlsHome'),' ',parameters('adminVMName'),' ',variables('const_wlsAdminPort'),' ',parameters('wlsLDAPSSLCertificate'), ' ', parameters('aadsPublicIP'), ' ', variables('const_adminServerName'),' ', variables('const_wlsDomainPath'),' ',parameters('enableCustomSSL'),' ',base64(parameters('keyVaultCustomTrustKeyStorePassPhrase')),' ',base64(parameters('keyVaultCustomTrustKeyStoreType')))]", - "const_adminServerName": "admin", - "const_managedVMPrefix": "[concat(parameters('managedServerPrefix'),'VM')]", - "const_wlsAdminPort": "7005", - "const_wlsDomainPath": "[concat('/u01/domains/', parameters('wlsDomainName'))]", - "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", - "name_scriptAADConfiguration": "aadIntegration.sh" - }, - "resources": [ - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${dynamic.aad.start}", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(variables('const_managedVMPrefix'), add(copyIndex(), 1),'/newuserscript')]", - "location": "[parameters('location')]", - "copy": { - "name": "managedVirtualMachineExtensionLoop", - "count": "[parameters('dynamicClusterSize')]" - }, - "properties": { - "publisher": "Microsoft.Azure.Extensions", - "type": "CustomScript", - "typeHandlerVersion": "2.0", - "autoUpgradeMinorVersion": true, - "settings": { - "fileUris": [ - "[uri(parameters('_artifactsLocationAADTemplate'), concat('../scripts/', variables('name_scriptAADConfiguration'), parameters('_artifactsLocationSasToken')))]" - ] - }, - "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptAADConfiguration'),' <<< \"', variables('const_aadParameters'),' ', add(copyIndex(),1),'\"')]" - } - } - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(parameters('adminVMName'),'/newuserscript')]", - "location": "[parameters('location')]", - "dependsOn": [ - "managedVirtualMachineExtensionLoop" - ], - "properties": { - "publisher": "Microsoft.Azure.Extensions", - "type": "CustomScript", - "typeHandlerVersion": "2.0", - "autoUpgradeMinorVersion": true, - "settings": { - "fileUris": [ - "[uri(parameters('_artifactsLocationAADTemplate'), concat('../scripts/', variables('name_scriptAADConfiguration'), parameters('_artifactsLocationSasToken')))]" - ] - }, - "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptAADConfiguration'),' <<< \"', variables('const_aadParameters'),' ', 0,'\"')]" - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${dynamic.aad.end}", - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" - ], - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - } - ], - "outputs": { - "artifactsLocationPassedIn": { - "type": "string", - "value": "[parameters('_artifactsLocation')]" - } - } -} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/clusterCustomSSLTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/clusterCustomSSLTemplate.json index a915675a4..1cb112af3 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/clusterCustomSSLTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/clusterCustomSSLTemplate.json @@ -22,6 +22,18 @@ "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." } }, + "_globalResourceNameSuffix": { + "type": "string", + "metadata": { + "description": "A suffix to be appended to all resources created by this template." + } + }, + "const_guidTag" :{ + "type": "string", + "metadata": { + "description": "A unique tag for resources." + } + }, "adminPasswordOrKey": { "type": "securestring", "metadata": { @@ -66,10 +78,6 @@ "description": "Initial Number of Managed Servers that will be configured in the Dynamic Cluster" } }, - "guidValue": { - "type": "string", - "defaultValue": "[newGuid()]" - }, "location": { "type": "string", "metadata": { @@ -82,6 +90,12 @@ "description": "Provide managed server prefix name" } }, + "managedVMPrefix": { + "type": "string", + "metadata": { + "description": "Managed Server hosting VM name prefix." + } + }, "maxDynamicClusterSize": { "type": "int", "defaultValue": 10, @@ -89,6 +103,12 @@ "description": "Maximum Number of Managed Servers allowed to be configured in the Dynamic Cluster" } }, + "nsgName": { + "type": "string", + "metadata": { + "description": "Name of the Network Security Group." + } + }, "portsToExpose": { "type": "string", "defaultValue": "80,443,7001-9000", @@ -97,18 +117,28 @@ } }, "skuUrnVersion": { - "type": "string", - "defaultValue": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", - "allowedValues": [ - "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest", - "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest", - "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest", - "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest", - "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" - ], - "metadata": { - "description": "The Oracle Linux image with Weblogic and Java preinstalled. Semicolon separated string of Sku, URN, and Version" - } + "type": "string", + "defaultValue": "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", + "allowedValues": [ + "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", + "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest", + "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest", + "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest", + "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest", + "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest", + "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest", + "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest", + "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest", + "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel76;Oracle:weblogic-122140-jdk8-rhel76:owls-122140-jdk8-rhel76;latest", + "owls-141100-jdk8-rhel76;Oracle:weblogic-141100-jdk8-rhel76:owls-141100-jdk8-rhel76;latest", + "owls-141100-jdk11-rhel76;Oracle:weblogic-141100-jdk11-rhel76:owls-141100-jdk11-rhel76;latest" + ], + "metadata": { + "description": "The Oracle Linux image with Weblogic and Java preinstalled. Semicolon separated string of Sku, URN, and Version" + } }, "usePreviewImage": { "type": "bool", @@ -124,13 +154,61 @@ "description": "Bool value, if it's set to true, a system assigned managed identity will to be created for the VM(s)" } }, - "vmSizeSelect": { + "vmSize": { "type": "string", "defaultValue": "Standard_A3", "metadata": { "description": "Select appropriate VM Size as per requirement" } }, + "virtualNetworkNewOrExisting": { + "type": "string", + "defaultValue": "new", + "allowedValues": [ + "new", + "existing" + ], + "metadata": { + "description": "Specify whether to create a new or existing virtual network for the VM." + } + }, + "virtualNetworkName": { + "type": "string", + "defaultValue": "wls-vnet", + "metadata": { + "description": "Name of the existing or new VNET" + } + }, + "virtualNetworkResourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "Resource group of Virtual network" + } + }, + "addressPrefixes": { + "type": "array", + "defaultValue": [ + "10.0.0.0/28" + ], + "metadata": { + "description": "Address prefix of the VNET." + } + }, + "subnetName": { + "type": "string", + "defaultValue": "wls-subnet", + "metadata": { + "description": "Name of the existing or new Subnet" + } + }, + "subnetPrefix": { + "type": "string", + "defaultValue": "10.0.0.0/29", + "metadata": { + "description": "Address prefix of the subnet" + } + }, "wlsDomainName": { "type": "string", "metadata": { @@ -149,65 +227,79 @@ "description": "Username for your Weblogic domain name" } }, - "enableHTTPAdminListenPort":{ + "enableHTTPAdminListenPort": { "type": "bool", "defaultValue": true, "metadata": { "description": "Boolean value indicating, if WebLogic Admin Server HTTP Listen Port is enabled or not" } }, - "enableCustomSSL":{ - "defaultValue":true, + "enableCustomSSL": { + "defaultValue": true, + "type": "bool", + "metadata": { + "description": "Boolean value indicating, if custom SSL is enabled or not" + } + }, + "enableDNSConfiguration": { + "defaultValue": false, "type": "bool", "metadata": { - "description": "Boolean value indicating, if custom SSL is enabled or not" + "description": "Boolean value indicating, if DNS Zone Configuration is enabled or not" } }, - "keyVaultCustomIdentityKeyStoreData": { + "customDNSNameForAdminServer": { + "type": "string", + "defaultValue": "none", + "metadata": { + "description": "Custom DNS Name for WebLogic Admin Server" + } + }, + "sslCustomIdentityKeyStoreData": { "type": "securestring", "metadata": { "description": "Weblogic Custom Identity Keystore Data" } }, - "keyVaultCustomIdentityKeyStorePassPhrase": { + "sslCustomIdentityKeyStorePassPhrase": { "type": "securestring", "metadata": { "description": "Weblogic Custom Identity Keystore Passphrase" } }, - "keyVaultCustomIdentityKeyStoreType": { + "sslCustomIdentityKeyStoreType": { "type": "string", "metadata": { "description": "Weblogic Custom Identity Keystore Type" }, "defaultValue": "JKS" }, - "keyVaultCustomTrustKeyStoreData": { + "sslCustomTrustKeyStoreData": { "type": "securestring", "metadata": { "description": "Weblogic Custom Trust Store Data" } }, - "keyVaultCustomTrustKeyStorePassPhrase": { + "sslCustomTrustKeyStorePassPhrase": { "type": "securestring", "metadata": { "description": "Weblogic Custom Trust Store Passphrase" } }, - "keyVaultCustomTrustKeyStoreType": { + "sslCustomTrustKeyStoreType": { "type": "string", "metadata": { "description": "Weblogic Custom Trust Store Type" }, "defaultValue": "JKS" }, - "keyVaultPrivateKeyAlias": { + "sslPrivateKeyAlias": { "type": "string", "metadata": { "description": "Weblogic Server Private Key Alias" } }, - "keyVaultPrivateKeyPassPhrase": { + "sslPrivateKeyPassPhrase": { "type": "securestring", "metadata": { "description": "Weblogic Server Private Key Pass Phrase" @@ -215,7 +307,7 @@ } }, "variables": { - "const_addressPrefix": "10.0.0.0/16", + "const_addressPrefix": "[parameters('addressPrefixes')]", "const_hyphen": "-", "const_imageOffer": "[concat('weblogic',variables('const_hyphen'), split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[1],variables('const_hyphen'),split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[2],variables('const_hyphen'),split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[3],if(parameters('usePreviewImage'),'-preview',''))]", "const_imagePublisher": "oracle", @@ -230,35 +322,42 @@ ] } }, - "const_managedVMPrefix": "[concat(parameters('managedServerPrefix'),'VM')]", + "const_managedVMPrefix": "[concat(parameters('managedVMPrefix'),'VM')]", "const_mountPointPath": "[concat('/mnt/', variables('name_share'))]", "const_publicIPAddressType": "Dynamic", "const_requiredPortrange": ",65200-65535,5556", "const_storageAccountType": "Standard_LRS", - "const_subnetPrefix": "10.0.0.0/24", + "const_subnetPrefix": "[parameters('subnetPrefix')]", "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", - "const_vmSize": "[parameters('vmSizeSelect')]", + "const_vmSize": "[parameters('vmSize')]", "name_linuxImageOfferSKU": "[first(split(parameters('skuUrnVersion'), ';'))]", "name_linuxImageVersion": "[last(split(parameters('skuUrnVersion'),';'))]", - "name_networkSecurityGroup": "[concat(parameters('dnsLabelPrefix'), '-nsg')]", - "name_nic": "NIC", - "name_outputAdminHost": "[concat(parameters('adminVMName'),variables('name_publicIPAddress'))]", - "name_publicIPAddress": "PublicIP", + "name_nic": "_NIC", + "name_nic_with_pub_ip": "[concat(variables('name_nic'), '_with_pub_ip')]", + "name_nic_without_pub_ip": "[concat(variables('name_nic'), '_without_pub_ip')]", + "name_outputAdminHost_with_pub_ip": "[concat(parameters('adminVMName'),variables('name_publicIPAddress'))]", + "name_outputAdminHost_without_pub_ip": "[concat(parameters('adminVMName'),variables('name_nic_without_pub_ip'))]", + "name_publicIPAddress": "_PublicIP", "name_scriptFile": "setupDynamicClusterDomain.sh", "name_share": "wlsshare", - "name_storageAccount": "[concat(take(replace(parameters('guidValue'),'-',''),6),'olvm')]", - "name_subnet": "Subnet", - "name_virtualNetwork": "[concat(parameters('wlsDomainName'),'_VNET')]", + "name_storageAccount": "[concat('olvmstg', parameters('_globalResourceNameSuffix'))]", + "name_subnet": "[parameters('subnetName')]", + "name_virtualNetwork": "[parameters('virtualNetworkName')]", + "name_privateSaEndpoint": "[concat('saep', parameters('_globalResourceNameSuffix'))]", "ref_fileService": "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('name_storageAccount'), 'default')]", - "ref_networkSecurityGroup": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('name_networkSecurityGroup'))]", + "ref_networkSecurityGroup": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('nsgName'))]", "ref_storage": "[resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount'))]", - "ref_subnet": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]", - "t3AdminPort": "[if(not(parameters('enableHTTPAdminListenPort')),'7005','7001')]" + "ref_subnet": "[resourceId(parameters('virtualNetworkResourceGroupName'), 'Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]", + "t3AdminPort": "[if(not(parameters('enableHTTPAdminListenPort')),'7005','7001')]", + "name_customHostnameGeneratorscriptFile": "generateCustomHostNameVerifier.sh", + "name_customHostnameVerifierJavaFile": "src/main/java/WebLogicCustomHostNameVerifier.java", + "name_customHostnameValuesTemplate": "src/main/java/HostNameValuesTemplate.txt", + "name_customHostnameVerifierTest": "src/test/java/WebLogicCustomHostNameVerifierTest.java" }, "resources": [ { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${dynamic.cluster.start}", "properties": { "mode": "Incremental", @@ -271,9 +370,24 @@ } }, { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${dynamic.ssl.start}", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "apiVersion": "${azure.apiVersionForNetworkSecurityGroups}", "type": "Microsoft.Network/networkSecurityGroups", - "apiVersion": "${azure.apiVersion}", - "name": "[variables('name_networkSecurityGroup')]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", + "name": "[parameters('nsgName')]", "location": "[parameters('location')]", "properties": { "securityRules": [ @@ -321,44 +435,71 @@ }, { "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "${azure.apiVersion2}", + "apiVersion": "${azure.apiVersionForStorage}", "name": "[variables('name_storageAccount')]", "location": "[parameters('location')]", "sku": { "name": "[variables('const_storageAccountType')]" }, - "kind": "Storage", + "kind": "StorageV2", "properties": { "supportsHttpsTrafficOnly": false } }, { - "type": "Microsoft.Storage/storageAccounts/fileServices", - "apiVersion": "${azure.apiVersion2}", - "name": "[concat(variables('name_storageAccount'), '/default')]", - "dependsOn": [ - "[variables('ref_storage')]" - ], - "sku": { - "name": "Standard_LRS", - "tier": "Standard" - } - }, - { - "type": "Microsoft.Storage/storageAccounts/fileServices/shares", - "apiVersion": "${azure.apiVersion2}", - "name": "[concat(variables('name_storageAccount'), '/default/', variables('name_share'))]", - "dependsOn": [ - "[variables('ref_fileService')]", - "[variables('ref_storage')]" - ], - "properties": { - "shareQuota": 5 - } - }, + "apiVersion": "${azure.apiVersionForPrivateEndpoint}", + "name": "[variables('name_privateSaEndpoint')]", + "type": "Microsoft.Network/privateEndpoints", + "location": "[parameters('location')]", + "properties": { + "privateLinkServiceConnections": [ + { + "name": "[variables('name_privateSaEndpoint')]", + "properties": { + "privateLinkServiceId": "[resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount'))]", + "groupIds": [ + "file" + ] + } + } + ], + "subnet": { + "id": "[variables('ref_subnet')]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount'))]", + "[variables('name_virtualNetwork')]" + ] + }, + { + "type": "Microsoft.Storage/storageAccounts/fileServices", + "apiVersion": "${azure.apiVersionForStorageFileService}", + "name": "[concat(variables('name_storageAccount'), '/default')]", + "dependsOn": [ + "[variables('ref_storage')]" + ], + "sku": { + "name": "Standard_LRS", + "tier": "Standard" + } + }, + { + "type": "Microsoft.Storage/storageAccounts/fileServices/shares", + "apiVersion": "${azure.apiVersionForStorageFileService}", + "name": "[concat(variables('name_storageAccount'), '/default/', variables('name_share'))]", + "dependsOn": [ + "[variables('ref_fileService')]", + "[variables('ref_storage')]" + ], + "properties": { + "shareQuota": 5 + } + }, { + "apiVersion": "${azure.apiVersionForPublicIPAddresses}", "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "${azure.apiVersion}", + "tags": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'existing'),createObject(parameters('const_guidTag'),''),createObject())]", "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_publicIPAddress')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_publicIPAddress')))]", "location": "[parameters('location')]", "copy": { @@ -368,13 +509,14 @@ "properties": { "publicIPAllocationMethod": "[variables('const_publicIPAddressType')]", "dnsSettings": { - "domainNameLabel": "[concat(toLower(parameters('dnsLabelPrefix')),copyindex(),'-',take(replace(parameters('guidValue'),'-',''),10),'-',toLower(parameters('wlsDomainName')))]" + "domainNameLabel": "[take(concat(toLower(parameters('dnsLabelPrefix')), copyindex(),'-', parameters('_globalResourceNameSuffix'),'-',toLower(parameters('wlsDomainName'))), 50)]" } } }, { + "apiVersion": "${azure.apiVersionForVirtualNetworks}", "type": "Microsoft.Network/virtualNetworks", - "apiVersion": "${azure.apiVersion}", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", "name": "[variables('name_virtualNetwork')]", "location": "[parameters('location')]", "dependsOn": [ @@ -382,9 +524,7 @@ ], "properties": { "addressSpace": { - "addressPrefixes": [ - "[variables('const_addressPrefix')]" - ] + "addressPrefixes": "[variables('const_addressPrefix')]" }, "subnets": [ { @@ -400,12 +540,13 @@ } }, { + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "${azure.apiVersion}", - "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_nic')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic')))]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", + "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_nic_with_pub_ip')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic_with_pub_ip')))]", "location": "[parameters('location')]", "copy": { - "name": "nicLoop", + "name": "nicLoop_public_ip", "count": "[add(parameters('dynamicClusterSize'),1)]" }, "dependsOn": [ @@ -433,8 +574,42 @@ } }, { + "type": "Microsoft.Network/networkInterfaces", + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'existing')]", + "name": "[if(equals(copyIndex(),0),variables('name_outputAdminHost_without_pub_ip'),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic_without_pub_ip')))]", + "location": "[parameters('location')]", + "copy": { + "name": "nicLoop_private_ip", + "count": "[add(parameters('dynamicClusterSize'),1)]" + }, + "dependsOn": [ + "[variables('name_virtualNetwork')]", + "publicIPLoop" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses',if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_publicIPAddress')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_publicIPAddress'))))]" + }, + "subnet": { + "id": "[variables('ref_subnet')]" + } + } + } + ], + "dnsSettings": { + "internalDnsNameLabel": "[if(equals(copyIndex(),0),parameters('adminVMName'),concat(variables('const_managedVMPrefix'), copyIndex()))]" + } + } + }, + { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "${azure.apiVersion}", "name": "[if(equals(copyIndex(),0),parameters('adminVMName'),concat(variables('const_managedVMPrefix'), copyIndex()))]", "location": "[parameters('location')]", "copy": { @@ -442,7 +617,8 @@ "count": "[add(parameters('dynamicClusterSize'),1)]" }, "dependsOn": [ - "nicLoop" + "nicLoop_public_ip", + "nicLoop_private_ip" ], "identity": "[if(parameters('useSystemAssignedManagedIdentity'), json('{\"type\":\"SystemAssigned\"}'), null())]", "properties": { @@ -467,29 +643,19 @@ "managedDisk": { "storageAccountType": "Standard_LRS" } - }, - "dataDisks": [ - { - "lun": 0, - "createOption": "FromImage", - "diskSizeGB": 900, - "managedDisk": { - "storageAccountType": "Standard_LRS" - } - } - ] + } }, "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces',if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_nic')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic'))))]" + "id": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), resourceId('Microsoft.Network/networkInterfaces',if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_nic_with_pub_ip')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic_with_pub_ip')))), resourceId('Microsoft.Network/networkInterfaces',if(equals(copyIndex(),0),variables('name_outputAdminHost_without_pub_ip'),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic_without_pub_ip')))))]" } ] }, "diagnosticsProfile": { "bootDiagnostics": { "enabled": true, - "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount')), '${azure.apiVersion2}').primaryEndpoints.blob]" + "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount')), '${azure.apiVersionForStorage}').primaryEndpoints.blob]" } } }, @@ -500,8 +666,8 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),'/newuserscript'),concat(variables('const_managedVMPrefix'),copyIndex(),'/newuserscript'))]", "location": "[parameters('location')]", "copy": { @@ -518,17 +684,38 @@ "autoUpgradeMinorVersion": true, "settings": { "fileUris": [ - "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../scripts/', variables('name_scriptFile'), parameters('_artifactsLocationSasToken')))]" + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../scripts/', variables('name_scriptFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameGeneratorscriptFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierJavaFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameValuesTemplate'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierTest'), parameters('_artifactsLocationSasToken')))]" ] }, "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'),' <<< \"',parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('managedServerPrefix'),' ',copyindex(),' ',variables('const_managedVMPrefix'),' ',parameters('maxDynamicClusterSize'),' ',parameters('dynamicClusterSize'),' ',parameters('adminVMName'),' ', variables('const_wlsHome'),' ',variables('name_storageAccount'),' ',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount')), '2019-04-01').keys[0].value,' ',variables('const_mountPointPath'),' ',string(parameters('enableHTTPAdminListenPort')),' ',string(parameters('enableCustomSSL')),' ',base64(parameters('keyVaultCustomIdentityKeyStoreData')),' ',base64(parameters('keyVaultCustomIdentityKeyStorePassPhrase')),' ',base64(parameters('keyVaultCustomIdentityKeyStoreType')),' ',base64(parameters('keyVaultCustomTrustKeyStoreData')),' ',base64(parameters('keyVaultCustomTrustKeyStorePassPhrase')),' ',base64(parameters('keyVaultCustomTrustKeyStoreType')),' ',base64(parameters('keyVaultPrivateKeyAlias')),' ',base64(parameters('keyVaultPrivateKeyPassPhrase')),'\"')]" + "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'),' <<< \"',parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('managedServerPrefix'),' ',copyindex(),' ',variables('const_managedVMPrefix'),' ',parameters('maxDynamicClusterSize'),' ',parameters('dynamicClusterSize'),' ',parameters('adminVMName'),' ', variables('const_wlsHome'),' ',variables('name_storageAccount'),' ',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount')), '${azure.apiVersionForStorage}').keys[0].value,' ',variables('const_mountPointPath'),' ',string(parameters('enableHTTPAdminListenPort')),' ',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), if(parameters('enableDNSConfiguration'),parameters('customDNSNameForAdminServer'),reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn), reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),' ',parameters('dnsLabelPrefix'),' ',parameters('location'),' ', parameters('virtualNetworkNewOrExisting'),' ',reference(resourceId('Microsoft.Network/privateEndpoints/', variables('name_privateSaEndpoint')), '${azure.apiVersionForPrivateEndpoint}').customDnsConfigs[0].ipAddresses[0], ' ',string(parameters('enableCustomSSL')),' ',base64(parameters('sslCustomIdentityKeyStoreData')),' ',base64(parameters('sslCustomIdentityKeyStorePassPhrase')),' ',base64(parameters('sslCustomIdentityKeyStoreType')),' ',base64(parameters('sslCustomTrustKeyStoreData')),' ',base64(parameters('sslCustomTrustKeyStorePassPhrase')),' ',base64(parameters('sslCustomTrustKeyStoreType')),' ',base64(parameters('sslPrivateKeyAlias')),' ',base64(parameters('sslPrivateKeyPassPhrase')),'\"')]" + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${dynamic.ssl.end}", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] } } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${dynamic.cluster.end}", "dependsOn": [ "virtualMachineExtensionLoop" @@ -545,9 +732,9 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-122130-jdk8-ol74}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122130-jdk8-ol74'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk11-ol91}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol91'), bool('true'), bool('false'))]", "dependsOn": [ "virtualMachineExtensionLoop" ], @@ -563,9 +750,9 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-122130-jdk8-ol73}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'from.owls-122130-jdk8-ol73'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk11-ol87}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol87'), bool('true'), bool('false'))]", "dependsOn": [ "virtualMachineExtensionLoop" ], @@ -581,7 +768,79 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk8-ol91}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol91'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk8-ol87}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol87'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-122140-jdk8-ol91}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-ol91'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-122140-jdk8-ol87}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-ol87'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${from.owls-122140-jdk8-ol76}", "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'from.owls-122140-jdk8-ol76'), bool('true'), bool('false'))]", "dependsOn": [ @@ -599,7 +858,7 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${from.owls-141100-jdk8-ol76}", "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol76'), bool('true'), bool('false'))]", "dependsOn": [ @@ -617,7 +876,7 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${from.owls-141100-jdk11-ol76}", "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol76'), bool('true'), bool('false'))]", "dependsOn": [ @@ -632,6 +891,114 @@ ] } } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk11-rhel87}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-rhel87'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk8-rhel87}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-rhel87'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-122140-jdk8-rhel87}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-rhel87'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-122140-jdk8-rhel76}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-rhel76'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk8-rhel76}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-rhel76'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk11-rhel76}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-rhel76'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } } ], "outputs": { @@ -649,15 +1016,15 @@ }, "adminHostName": { "type": "string", - "value": "[reference(variables('name_outputAdminHost'), '${azure.apiVersion}').dnsSettings.fqdn]" + "value": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn, reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress)]" }, "adminConsole": { "type": "string", - "value": "[concat('http://',reference(variables('name_outputAdminHost'), '${azure.apiVersion}').dnsSettings.fqdn,':',variables('t3AdminPort'),'/console')]" + "value": "[uri(concat('http://',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'),reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn,reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7001/console/'),'')]" }, "adminSecuredConsole": { "type": "string", - "value": "[concat('https://',reference(variables('name_outputAdminHost'), '${azure.apiVersion}').dnsSettings.fqdn,':7002/console')]" + "value": "[uri(concat('https://',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'),reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn,reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7002/console/'),'')]" }, "storageAccountName": { "type": "string", @@ -667,9 +1034,9 @@ "type": "string", "value": "[variables('name_virtualNetwork')]" }, - "adminRestMgmtURL":{ + "adminRestMgmtURL": { "type": "string", - "value": "[concat('http://',parameters('adminVMName'),':',variables('t3AdminPort'),'/management/weblogic/latest')]" + "value": "[uri(format('http://{0}:{1}',parameters('adminVMName'),variables('t3AdminPort')), 'management/weblogic/latest')]" } } } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/clusterTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/clusterTemplate.json index cdc3682a6..c72937b6a 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/clusterTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/clusterTemplate.json @@ -22,6 +22,18 @@ "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." } }, + "_globalResourceNameSuffix": { + "type": "string", + "metadata": { + "description": "A suffix to be appended to all resources created by this template." + } + }, + "const_guidTag" :{ + "type": "string", + "metadata": { + "description": "A unique tag for resources." + } + }, "adminPasswordOrKey": { "type": "securestring", "metadata": { @@ -66,10 +78,6 @@ "description": "Initial Number of Managed Servers that will be configured in the Dynamic Cluster" } }, - "guidValue": { - "type": "string", - "defaultValue": "[newGuid()]" - }, "location": { "type": "string", "metadata": { @@ -82,6 +90,12 @@ "description": "Provide managed server prefix name" } }, + "managedVMPrefix": { + "type": "string", + "metadata": { + "description": "Managed Server hosting VM name prefix." + } + }, "maxDynamicClusterSize": { "type": "int", "defaultValue": 10, @@ -89,6 +103,12 @@ "description": "Maximum Number of Managed Servers allowed to be configured in the Dynamic Cluster" } }, + "nsgName": { + "type": "string", + "metadata": { + "description": "Name of the Network Security Group." + } + }, "portsToExpose": { "type": "string", "defaultValue": "80,443,7001-9000", @@ -98,13 +118,23 @@ }, "skuUrnVersion": { "type": "string", - "defaultValue": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "defaultValue": "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", "allowedValues": [ - "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest", - "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest", + "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", + "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest", + "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest", + "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest", + "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest", + "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest", "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest", "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest", - "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" + "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest", + "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel76;Oracle:weblogic-122140-jdk8-rhel76:owls-122140-jdk8-rhel76;latest", + "owls-141100-jdk8-rhel76;Oracle:weblogic-141100-jdk8-rhel76:owls-141100-jdk8-rhel76;latest", + "owls-141100-jdk11-rhel76;Oracle:weblogic-141100-jdk11-rhel76:owls-141100-jdk11-rhel76;latest" ], "metadata": { "description": "The Oracle Linux image with Weblogic and Java preinstalled. Semicolon separated string of Sku, URN, and Version" @@ -124,13 +154,61 @@ "description": "Bool value, if it's set to true, a system assigned managed identity will to be created for the VM(s)" } }, - "vmSizeSelect": { + "vmSize": { "type": "string", "defaultValue": "Standard_A3", "metadata": { "description": "Select appropriate VM Size as per requirement" } }, + "virtualNetworkNewOrExisting": { + "type": "string", + "defaultValue": "new", + "allowedValues": [ + "new", + "existing" + ], + "metadata": { + "description": "Specify whether to create a new or existing virtual network for the VM." + } + }, + "virtualNetworkName": { + "type": "string", + "defaultValue": "wls-vnet", + "metadata": { + "description": "Name of the existing or new VNET" + } + }, + "virtualNetworkResourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "Resource group of Virtual network" + } + }, + "addressPrefixes": { + "type": "array", + "defaultValue": [ + "10.0.0.0/28" + ], + "metadata": { + "description": "Address prefix of the VNET." + } + }, + "subnetName": { + "type": "string", + "defaultValue": "wls-subnet", + "metadata": { + "description": "Name of the existing or new Subnet" + } + }, + "subnetPrefix": { + "type": "string", + "defaultValue": "10.0.0.0/29", + "metadata": { + "description": "Address prefix of the subnet" + } + }, "wlsDomainName": { "type": "string", "metadata": { @@ -155,10 +233,24 @@ "metadata": { "description": "Boolean value indicating, if WebLogic Admin Server HTTP Listen Port is enabled or not" } + }, + "enableDNSConfiguration": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "Boolean value indicating, if DNS Zone Configuration is enabled or not" + } + }, + "customDNSNameForAdminServer": { + "type": "string", + "defaultValue": "none", + "metadata": { + "description": "Custom DNS Name for WebLogic Admin Server" + } } }, "variables": { - "const_addressPrefix": "10.0.0.0/16", + "const_addressPrefix": "[parameters('addressPrefixes')]", "const_hyphen": "-", "const_imageOffer": "[concat('weblogic',variables('const_hyphen'), split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[1],variables('const_hyphen'),split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[2],variables('const_hyphen'),split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[3],if(parameters('usePreviewImage'),'-preview',''))]", "const_imagePublisher": "oracle", @@ -173,35 +265,42 @@ ] } }, - "const_managedVMPrefix": "[concat(parameters('managedServerPrefix'),'VM')]", + "const_managedVMPrefix": "[concat(parameters('managedVMPrefix'),'VM')]", "const_mountPointPath": "[concat('/mnt/', variables('name_share'))]", "const_publicIPAddressType": "Dynamic", "const_requiredPortrange": ",65200-65535,5556", "const_storageAccountType": "Standard_LRS", - "const_subnetPrefix": "10.0.0.0/24", + "const_subnetPrefix": "[parameters('subnetPrefix')]", "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", - "const_vmSize": "[parameters('vmSizeSelect')]", + "const_vmSize": "[parameters('vmSize')]", "name_linuxImageOfferSKU": "[first(split(parameters('skuUrnVersion'), ';'))]", "name_linuxImageVersion": "[last(split(parameters('skuUrnVersion'),';'))]", - "name_networkSecurityGroup": "[concat(parameters('dnsLabelPrefix'), '-nsg')]", - "name_nic": "NIC", - "name_outputAdminHost": "[concat(parameters('adminVMName'),variables('name_publicIPAddress'))]", - "name_publicIPAddress": "PublicIP", + "name_nic": "_NIC", + "name_nic_with_pub_ip": "[concat(variables('name_nic'), '_with_pub_ip')]", + "name_nic_without_pub_ip": "[concat(variables('name_nic'), '_without_pub_ip')]", + "name_outputAdminHost_with_pub_ip": "[concat(parameters('adminVMName'),variables('name_publicIPAddress'))]", + "name_outputAdminHost_without_pub_ip": "[concat(parameters('adminVMName'),variables('name_nic_without_pub_ip'))]", + "name_publicIPAddress": "_PublicIP", "name_scriptFile": "setupDynamicClusterDomain.sh", "name_share": "wlsshare", - "name_storageAccount": "[concat(take(replace(parameters('guidValue'),'-',''),6),'olvm')]", - "name_subnet": "Subnet", - "name_virtualNetwork": "[concat(parameters('wlsDomainName'),'_VNET')]", + "name_storageAccount": "[concat('olvmstg', parameters('_globalResourceNameSuffix'))]", + "name_subnet": "[parameters('subnetName')]", + "name_virtualNetwork": "[parameters('virtualNetworkName')]", + "name_privateSaEndpoint": "[concat('saep', parameters('_globalResourceNameSuffix'))]", "ref_fileService": "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('name_storageAccount'), 'default')]", - "ref_networkSecurityGroup": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('name_networkSecurityGroup'))]", + "ref_networkSecurityGroup": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('nsgName'))]", "ref_storage": "[resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount'))]", - "ref_subnet": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]", - "t3AdminPort": "[if(not(parameters('enableHTTPAdminListenPort')),'7005','7001')]" + "ref_subnet": "[resourceId(parameters('virtualNetworkResourceGroupName'), 'Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]", + "t3AdminPort": "[if(not(parameters('enableHTTPAdminListenPort')),'7005','7001')]", + "name_customHostnameGeneratorscriptFile": "generateCustomHostNameVerifier.sh", + "name_customHostnameVerifierJavaFile": "src/main/java/WebLogicCustomHostNameVerifier.java", + "name_customHostnameValuesTemplate": "src/main/java/HostNameValuesTemplate.txt", + "name_customHostnameVerifierTest": "src/test/java/WebLogicCustomHostNameVerifierTest.java" }, "resources": [ { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${dynamic.cluster.start}", "properties": { "mode": "Incremental", @@ -214,9 +313,10 @@ } }, { + "apiVersion": "${azure.apiVersionForNetworkSecurityGroups}", "type": "Microsoft.Network/networkSecurityGroups", - "apiVersion": "${azure.apiVersion}", - "name": "[variables('name_networkSecurityGroup')]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", + "name": "[parameters('nsgName')]", "location": "[parameters('location')]", "properties": { "securityRules": [ @@ -264,20 +364,46 @@ }, { "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "${azure.apiVersion2}", + "apiVersion": "${azure.apiVersionForStorage}", "name": "[variables('name_storageAccount')]", "location": "[parameters('location')]", "sku": { "name": "[variables('const_storageAccountType')]" }, - "kind": "Storage", + "kind": "StorageV2", "properties": { "supportsHttpsTrafficOnly": false } }, + { + "apiVersion": "${azure.apiVersionForPrivateEndpoint}", + "name": "[variables('name_privateSaEndpoint')]", + "type": "Microsoft.Network/privateEndpoints", + "location": "[parameters('location')]", + "properties": { + "privateLinkServiceConnections": [ + { + "name": "[variables('name_privateSaEndpoint')]", + "properties": { + "privateLinkServiceId": "[resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount'))]", + "groupIds": [ + "file" + ] + } + } + ], + "subnet": { + "id": "[variables('ref_subnet')]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount'))]", + "[variables('name_virtualNetwork')]" + ] + }, { "type": "Microsoft.Storage/storageAccounts/fileServices", - "apiVersion": "${azure.apiVersion2}", + "apiVersion": "${azure.apiVersionForStorageFileService}", "name": "[concat(variables('name_storageAccount'), '/default')]", "dependsOn": [ "[variables('ref_storage')]" @@ -289,7 +415,7 @@ }, { "type": "Microsoft.Storage/storageAccounts/fileServices/shares", - "apiVersion": "${azure.apiVersion2}", + "apiVersion": "${azure.apiVersionForStorageFileService}", "name": "[concat(variables('name_storageAccount'), '/default/', variables('name_share'))]", "dependsOn": [ "[variables('ref_fileService')]", @@ -300,8 +426,9 @@ } }, { + "apiVersion": "${azure.apiVersionForPublicIPAddresses}", "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "${azure.apiVersion}", + "tags": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'existing'),createObject(parameters('const_guidTag'),''),createObject())]", "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_publicIPAddress')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_publicIPAddress')))]", "location": "[parameters('location')]", "copy": { @@ -311,13 +438,14 @@ "properties": { "publicIPAllocationMethod": "[variables('const_publicIPAddressType')]", "dnsSettings": { - "domainNameLabel": "[concat(toLower(parameters('dnsLabelPrefix')),copyindex(),'-',take(replace(parameters('guidValue'),'-',''),10),'-',toLower(parameters('wlsDomainName')))]" + "domainNameLabel": "[take(concat(toLower(parameters('dnsLabelPrefix')), copyindex(),'-', parameters('_globalResourceNameSuffix'),'-',toLower(parameters('wlsDomainName'))), 50)]" } } }, { + "apiVersion": "${azure.apiVersionForVirtualNetworks}", "type": "Microsoft.Network/virtualNetworks", - "apiVersion": "${azure.apiVersion}", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", "name": "[variables('name_virtualNetwork')]", "location": "[parameters('location')]", "dependsOn": [ @@ -325,9 +453,7 @@ ], "properties": { "addressSpace": { - "addressPrefixes": [ - "[variables('const_addressPrefix')]" - ] + "addressPrefixes": "[variables('const_addressPrefix')]" }, "subnets": [ { @@ -343,12 +469,13 @@ } }, { + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "${azure.apiVersion}", - "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_nic')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic')))]", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", + "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_nic_with_pub_ip')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic_with_pub_ip')))]", "location": "[parameters('location')]", "copy": { - "name": "nicLoop", + "name": "nicLoop_public_ip", "count": "[add(parameters('dynamicClusterSize'),1)]" }, "dependsOn": [ @@ -376,8 +503,42 @@ } }, { + "type": "Microsoft.Network/networkInterfaces", + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'existing')]", + "name": "[if(equals(copyIndex(),0),variables('name_outputAdminHost_without_pub_ip'),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic_without_pub_ip')))]", + "location": "[parameters('location')]", + "copy": { + "name": "nicLoop_private_ip", + "count": "[add(parameters('dynamicClusterSize'),1)]" + }, + "dependsOn": [ + "[variables('name_virtualNetwork')]", + "publicIPLoop" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses',if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_publicIPAddress')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_publicIPAddress'))))]" + }, + "subnet": { + "id": "[variables('ref_subnet')]" + } + } + } + ], + "dnsSettings": { + "internalDnsNameLabel": "[if(equals(copyIndex(),0),parameters('adminVMName'),concat(variables('const_managedVMPrefix'), copyIndex()))]" + } + } + }, + { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "${azure.apiVersion}", "name": "[if(equals(copyIndex(),0),parameters('adminVMName'),concat(variables('const_managedVMPrefix'), copyIndex()))]", "location": "[parameters('location')]", "copy": { @@ -385,7 +546,8 @@ "count": "[add(parameters('dynamicClusterSize'),1)]" }, "dependsOn": [ - "nicLoop" + "nicLoop_public_ip", + "nicLoop_private_ip" ], "identity": "[if(parameters('useSystemAssignedManagedIdentity'), json('{\"type\":\"SystemAssigned\"}'), null())]", "properties": { @@ -410,29 +572,19 @@ "managedDisk": { "storageAccountType": "Standard_LRS" } - }, - "dataDisks": [ - { - "lun": 0, - "createOption": "FromImage", - "diskSizeGB": 900, - "managedDisk": { - "storageAccountType": "Standard_LRS" - } - } - ] + } }, "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces',if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_nic')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic'))))]" + "id": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), resourceId('Microsoft.Network/networkInterfaces',if(equals(copyIndex(),0),concat(parameters('adminVMName'),variables('name_nic_with_pub_ip')),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic_with_pub_ip')))), resourceId('Microsoft.Network/networkInterfaces',if(equals(copyIndex(),0),variables('name_outputAdminHost_without_pub_ip'),concat(variables('const_managedVMPrefix'), copyIndex(),variables('name_nic_without_pub_ip')))))]" } ] }, "diagnosticsProfile": { "bootDiagnostics": { "enabled": true, - "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount')), '${azure.apiVersion2}').primaryEndpoints.blob]" + "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount')), '${azure.apiVersionForStorage}').primaryEndpoints.blob]" } } }, @@ -443,8 +595,8 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),'/newuserscript'),concat(variables('const_managedVMPrefix'),copyIndex(),'/newuserscript'))]", "location": "[parameters('location')]", "copy": { @@ -461,17 +613,21 @@ "autoUpgradeMinorVersion": true, "settings": { "fileUris": [ - "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../scripts/', variables('name_scriptFile'), parameters('_artifactsLocationSasToken')))]" + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../scripts/', variables('name_scriptFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameGeneratorscriptFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierJavaFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameValuesTemplate'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationClusterTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierTest'), parameters('_artifactsLocationSasToken')))]" ] }, "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'),' <<< \"',parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('managedServerPrefix'),' ',copyindex(),' ',variables('const_managedVMPrefix'),' ',parameters('maxDynamicClusterSize'),' ',parameters('dynamicClusterSize'),' ',parameters('adminVMName'),' ', variables('const_wlsHome'),' ',variables('name_storageAccount'),' ',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount')), '2019-04-01').keys[0].value,' ',variables('const_mountPointPath'),' ',string(parameters('enableHTTPAdminListenPort')),' ','false','\"')]" + "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'),' <<< \"',parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('managedServerPrefix'),' ',copyindex(),' ',variables('const_managedVMPrefix'),' ',parameters('maxDynamicClusterSize'),' ',parameters('dynamicClusterSize'),' ',parameters('adminVMName'),' ', variables('const_wlsHome'),' ',variables('name_storageAccount'),' ',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('name_storageAccount')), '${azure.apiVersionForStorage}').keys[0].value,' ',variables('const_mountPointPath'),' ',string(parameters('enableHTTPAdminListenPort')),' ',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), if(parameters('enableDNSConfiguration'),parameters('customDNSNameForAdminServer'),reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn), reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),' ',parameters('dnsLabelPrefix'),' ',parameters('location'),' ',parameters('virtualNetworkNewOrExisting'),' ',reference(resourceId('Microsoft.Network/privateEndpoints/', variables('name_privateSaEndpoint')), '${azure.apiVersionForPrivateEndpoint}').customDnsConfigs[0].ipAddresses[0], ' ', 'false','\"')]" } } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${dynamic.cluster.end}", "dependsOn": [ "virtualMachineExtensionLoop" @@ -488,9 +644,63 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-122130-jdk8-ol74}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122130-jdk8-ol74'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk11-ol91}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol91'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk11-ol87}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol87'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk8-ol91}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol91'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk8-ol87}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol87'), bool('true'), bool('false'))]", "dependsOn": [ "virtualMachineExtensionLoop" ], @@ -506,9 +716,9 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-122130-jdk8-ol73}", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'from.owls-122130-jdk8-ol73'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-122140-jdk8-ol91}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-ol91'), bool('true'), bool('false'))]", "dependsOn": [ "virtualMachineExtensionLoop" ], @@ -524,7 +734,25 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-122140-jdk8-ol87}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-ol87'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${from.owls-122140-jdk8-ol76}", "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'from.owls-122140-jdk8-ol76'), bool('true'), bool('false'))]", "dependsOn": [ @@ -542,7 +770,7 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${from.owls-141100-jdk8-ol76}", "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol76'), bool('true'), bool('false'))]", "dependsOn": [ @@ -560,7 +788,7 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${from.owls-141100-jdk11-ol76}", "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol76'), bool('true'), bool('false'))]", "dependsOn": [ @@ -575,6 +803,114 @@ ] } } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk11-rhel87}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-rhel87'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk8-rhel87}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-rhel87'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-122140-jdk8-rhel87}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-rhel87'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-122140-jdk8-rhel76}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-rhel76'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk8-rhel76}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-rhel76'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk11-rhel76}", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-rhel76'), bool('true'), bool('false'))]", + "dependsOn": [ + "virtualMachineExtensionLoop" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } } ], "outputs": { @@ -592,15 +928,15 @@ }, "adminHostName": { "type": "string", - "value": "[reference(variables('name_outputAdminHost'), '${azure.apiVersion}').dnsSettings.fqdn]" + "value": "[if(equals(parameters('virtualNetworkNewOrExisting'), 'new'), reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn, reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress)]" }, "adminConsole": { "type": "string", - "value": "[concat('http://',reference(variables('name_outputAdminHost'), '${azure.apiVersion}').dnsSettings.fqdn,':',variables('t3AdminPort'),'/console')]" + "value": "[uri(concat('http://',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'),reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn,reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7001/console/'),'')]" }, "adminSecuredConsole": { "type": "string", - "value": "[concat('https://',reference(variables('name_outputAdminHost'), '${azure.apiVersion}').dnsSettings.fqdn,':7002/console')]" + "value": "[uri(concat('https://',if(equals(parameters('virtualNetworkNewOrExisting'), 'new'),reference(variables('name_outputAdminHost_with_pub_ip'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn,reference(variables('name_outputAdminHost_without_pub_ip')).ipConfigurations[0].properties.privateIPAddress),':7002/console/'),'')]" }, "storageAccountName": { "type": "string", @@ -612,7 +948,7 @@ }, "adminRestMgmtURL": { "type": "string", - "value": "[concat('http://',parameters('adminVMName'),':',variables('t3AdminPort'),'/management/weblogic/latest')]" + "value": "[uri(format('http://{0}:{1}',parameters('adminVMName'),variables('t3AdminPort')),'/management/weblogic/latest')]" } } } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/coherenceTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/coherenceTemplate.json index 0ee4f0072..915359efa 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/coherenceTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/coherenceTemplate.json @@ -22,6 +22,12 @@ }, "defaultValue": "" }, + "_globalResourceNameSuffix":{ + "type": "string", + "metadata": { + "description": "The suffix to be appended to the globally unique resource name" + } + }, "adminPasswordOrKey": { "type": "securestring", "metadata": { @@ -60,27 +66,6 @@ "description": "Unique DNS Name for the Public IP used to access the Virtual Machine." } }, - "elasticsearchEndpoint": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Endpoint of the Elasticsearch instance." - } - }, - "elasticsearchPassword": { - "type": "securestring", - "defaultValue": "[newGuid()]", - "metadata": { - "description": "The credentials to distribute message to Elasticsearch instance with REST API." - } - }, - "elasticsearchUserName": { - "type": "string", - "defaultValue": "elastic", - "metadata": { - "description": "The credentials to distribute message to Elasticsearch instance with REST API." - } - }, "enableCoherenceWebLocalStorage": { "defaultValue": true, "type": "bool", @@ -88,43 +73,23 @@ "description": "Specifies whether Local Storage is enabled for the Coherence*Web cluster tier." } }, - "enableELK": { - "defaultValue": false, - "type": "bool", - "metadata": { - "description": "If true, use the supplied parameters to distribute WebLogic Server logs to the Elasticsearch instance." - } - }, - "guidValue": { - "type": "string", - "defaultValue": "[newGuid()]" - }, "location": { "type": "string", "metadata": { "description": "Location for all resources." } }, - "logIndex": { + "managedServerPrefix": { "type": "string", - "defaultValue": "", - "metadata": { - "description": "Elasticsearch index you expect to export the logs to." - } - }, - "logsToIntegrate": { - "type": "array", - "defaultValue": [ "HTTPAccessLog", "ServerLog", "DomainLog", "DataSourceLog", "StandardErrorAndOutput", "NodeManagerLog" ], - "allowedValues": [ "HTTPAccessLog", "ServerLog", "DomainLog", "DataSourceLog", "StandardErrorAndOutput", "NodeManagerLog" ], + "defaultValue": "msp", "metadata": { - "description": "Specify the expeted logs to integrate, you must input at least one log." + "description": "Provide managed server prefix name" } }, - "managedServerPrefix": { + "managedVMNamePrefix": { "type": "string", - "defaultValue": "msp", "metadata": { - "description": "Provide managed server prefix name" + "description": "Managed VM name prefix" } }, "numberOfCoherenceCacheInstances": { @@ -138,13 +103,23 @@ }, "skuUrnVersion": { "type": "string", - "defaultValue": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "defaultValue": "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", "allowedValues": [ - "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest", - "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest", + "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", + "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest", + "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest", + "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest", + "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest", + "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest", "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest", "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest", - "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" + "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest", + "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel76;Oracle:weblogic-122140-jdk8-rhel76:owls-122140-jdk8-rhel76;latest", + "owls-141100-jdk8-rhel76;Oracle:weblogic-141100-jdk8-rhel76:owls-141100-jdk8-rhel76;latest", + "owls-141100-jdk11-rhel76;Oracle:weblogic-141100-jdk11-rhel76:owls-141100-jdk11-rhel76;latest" ], "metadata": { "description": "The Oracle Linux image with Weblogic and Java preinstalled. Semicolon separated string of Sku, URN, and Version" @@ -156,6 +131,13 @@ "description": "Name of storage account. One storage account can store 20 vitual machines with 2 VHDs of 500 IOPS." } }, + "subnetName": { + "type": "string", + "defaultValue": "wls-subnet", + "metadata": { + "description": "Name of the existing or new Subnet" + } + }, "usePreviewImage": { "type": "bool", "defaultValue": false, @@ -190,6 +172,34 @@ "description": "Username for your Weblogic domain name" } }, + "virtualNetworkResourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "Resource group of Virtual network" + } + }, + "virtualNetworkName": { + "type": "string", + "defaultValue": "wls-vnet", + "metadata": { + "description": "Name of the existing or new VNET" + } + }, + "enableDNSConfiguration": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "Boolean value indicating, if DNS Zone Configuration is enabled or not" + } + }, + "customDNSNameForAdminServer": { + "type": "string", + "defaultValue": "none", + "metadata": { + "description": "Custom DNS Name for WebLogic Admin Server" + } + }, "enableCustomSSL":{ "defaultValue":false, "type": "bool", @@ -197,56 +207,56 @@ "description": "Boolean value indicating, if custom SSL is enabled or not" } }, - "keyVaultCustomIdentityKeyStoreData": { + "sslCustomIdentityKeyStoreData": { "type": "securestring", "defaultValue":"", "metadata": { "description": "Weblogic Custom Identity Keystore Data" } }, - "keyVaultCustomIdentityKeyStorePassPhrase": { + "sslCustomIdentityKeyStorePassPhrase": { "type": "securestring", "defaultValue":"", "metadata": { "description": "Weblogic Custom Identity Keystore Passphrase" } }, - "keyVaultCustomIdentityKeyStoreType": { + "sslCustomIdentityKeyStoreType": { "type": "string", "metadata": { "description": "Weblogic Custom Identity Keystore Type" }, "defaultValue": "JKS" }, - "keyVaultCustomTrustKeyStoreData": { + "sslCustomTrustKeyStoreData": { "type": "securestring", "defaultValue":"", "metadata": { "description": "Weblogic Custom Trust Store Data" } }, - "keyVaultCustomTrustKeyStorePassPhrase": { + "sslCustomTrustKeyStorePassPhrase": { "type": "securestring", "defaultValue":"", "metadata": { "description": "Weblogic Custom Trust Store Passphrase" } }, - "keyVaultCustomTrustKeyStoreType": { + "sslCustomTrustKeyStoreType": { "type": "string", "metadata": { "description": "Weblogic Custom Trust Store Type" }, "defaultValue": "JKS" }, - "keyVaultPrivateKeyAlias": { + "sslPrivateKeyAlias": { "type": "string", "defaultValue":"null", "metadata": { "description": "Weblogic Server Private Key Alias" } }, - "keyVaultPrivateKeyPassPhrase": { + "sslPrivateKeyPassPhrase": { "type": "securestring", "defaultValue":"", "metadata": { @@ -271,7 +281,6 @@ }, "const_mountPointPath": "[concat('/mnt/', variables('name_share'))]", "const_publicIPAddressType": "Dynamic", - "const_singleQuote": "'", "const_vmSize": "[parameters('vmSizeSelectForCoherence')]", "const_wlsDomainPath": "/u01/domains", "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", @@ -280,13 +289,17 @@ "name_nic": "_NIC", "name_publicIPAddress": "_PublicIP", "name_scriptFile": "setupCoherence.sh", - "name_scriptELKConfiguration": "elkIntegrationForConfiguredCluster.sh", "name_share": "wlsshare", - "name_subnet": "Subnet", - "name_virtualNetwork": "[concat(parameters('wlsDomainName'),'_VNET')]", - "name_vmMachine": "[concat(parameters('managedServerPrefix'),'StorageVM')]", + "name_subnet": "[parameters('subnetName')]", + "name_virtualNetwork": "[parameters('virtualNetworkName')]", + "name_vmPrefix": "[concat(parameters('managedVMNamePrefix'), 'StorageVM')]", "name_wlsServerPrefix": "[concat(parameters('managedServerPrefix'),'Storage')]", - "ref_subnet": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]" + "ref_subnet": "[resourceId(parameters('virtualNetworkResourceGroupName'), 'Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]", + "name_customHostnameGeneratorscriptFile": "generateCustomHostNameVerifier.sh", + "name_customHostnameVerifierJavaFile": "src/main/java/WebLogicCustomHostNameVerifier.java", + "name_customHostnameValuesTemplate": "src/main/java/HostNameValuesTemplate.txt", + "name_customHostnameVerifierTest" : "src/test/java/WebLogicCustomHostNameVerifierTest.java" + }, "functions": [ { @@ -309,7 +322,7 @@ ], "resources": [ { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${dynamic.coherence.start}", "type": "Microsoft.Resources/deployments", "properties": { @@ -323,9 +336,9 @@ } }, { + "apiVersion": "${azure.apiVersionForPublicIPAddresses}", "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(variables('name_vmMachine'),copyIndex(1),variables('name_publicIPAddress'))]", + "name": "[concat(variables('name_vmPrefix'),copyIndex(1),variables('name_publicIPAddress'))]", "location": "[parameters('location')]", "copy": { "name": "publicIPLoop", @@ -334,27 +347,27 @@ "properties": { "publicIPAllocationMethod": "[variables('const_publicIPAddressType')]", "dnsSettings": { - "domainNameLabel": "[concat(toLower(parameters('dnsLabelPrefix')),copyindex(1),'-',take(replace(parameters('guidValue'),'-',''),10),'-',toLower(parameters('wlsDomainName')))]" + "domainNameLabel": "[take(concat(toLower(parameters('dnsLabelPrefix')), 'co', copyindex(),'-', parameters('_globalResourceNameSuffix'),'-',toLower(parameters('wlsDomainName'))), 50)]" } } }, { + "apiVersion": "${azure.apiVersionForVirtualNetworks}", "type": "Microsoft.Network/virtualNetworks/subnets", - "apiVersion": "${azure.apiVersion}", "name": "[concat(variables('name_virtualNetwork'), '/', variables('name_subnet'))]", "condition": "[and(empty(variables('name_virtualNetwork')), empty(variables('name_subnet')))]" }, { + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(variables('name_vmMachine'), copyIndex(1), variables('name_nic'))]", + "name": "[concat(variables('name_vmPrefix'), copyIndex(1), variables('name_nic'))]", "location": "[parameters('location')]", "copy": { "name": "nicLoop", "count": "[parameters('numberOfCoherenceCacheInstances')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/publicIPAddresses/', concat(variables('name_vmMachine'),copyIndex(1),variables('name_publicIPAddress')))]" + "[resourceId('Microsoft.Network/publicIPAddresses/', concat(variables('name_vmPrefix'),copyIndex(1),variables('name_publicIPAddress')))]" ], "properties": { "ipConfigurations": [ @@ -363,7 +376,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses',concat(variables('name_vmMachine'),copyIndex(1),variables('name_publicIPAddress')))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses',concat(variables('name_vmPrefix'),copyIndex(1),variables('name_publicIPAddress')))]" }, "subnet": { "id": "[variables('ref_subnet')]" @@ -372,14 +385,14 @@ } ], "dnsSettings": { - "internalDnsNameLabel": "[concat(variables('name_vmMachine'), copyIndex(1))]" + "internalDnsNameLabel": "[concat(variables('name_vmPrefix'), copyIndex(1))]" } } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(variables('name_vmMachine'), copyIndex(1))]", + "name": "[concat(variables('name_vmPrefix'), copyIndex(1))]", "location": "[parameters('location')]", "copy": { "name": "virtualMachineLoop", @@ -393,7 +406,7 @@ "vmSize": "[variables('const_vmSize')]" }, "osProfile": { - "computerName": "[concat(variables('name_vmMachine'), copyIndex(1))]", + "computerName": "[concat(variables('name_vmPrefix'), copyIndex(1))]", "adminUsername": "[parameters('adminUsername')]", "adminPassword": "[parameters('adminPasswordOrKey')]", "linuxConfiguration": "[if(equals(parameters('authenticationType'), 'password'), json('null'), variables('const_linuxConfiguration'))]" @@ -410,29 +423,19 @@ "managedDisk": { "storageAccountType": "Standard_LRS" } - }, - "dataDisks": [ - { - "lun": 0, - "createOption": "FromImage", - "diskSizeGB": 900, - "managedDisk": { - "storageAccountType": "Standard_LRS" - } - } - ] + } }, "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('name_vmMachine'), copyIndex(1), variables('name_nic')))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('name_vmPrefix'), copyIndex(1), variables('name_nic')))]" } ] }, "diagnosticsProfile": { "bootDiagnostics": { "enabled": true, - "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', parameters('storageAccountName')), '${azure.apiVersion2}').primaryEndpoints.blob]" + "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', parameters('storageAccountName')), '${azure.apiVersionForStorage}').primaryEndpoints.blob]" } } }, @@ -444,8 +447,8 @@ }, { "type": "Microsoft.Compute/virtualMachines/extensions", - "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),'/newuserscript'),concat(variables('name_vmMachine'), copyIndex(),'/newuserscript'))]", - "apiVersion": "${azure.apiVersion}", + "name": "[if(equals(copyIndex(),0),concat(parameters('adminVMName'),'/newuserscript'),concat(variables('name_vmPrefix'), copyIndex(),'/newuserscript'))]", + "apiVersion": "${azure.apiVersionForVirtualMachines}", "location": "[parameters('location')]", "copy": { "name": "virtualMachineExtensionLoop", @@ -462,16 +465,19 @@ "settings": { "fileUris": [ "[uri(parameters('_artifactsLocationCoherenceTemplate'), concat('../scripts/', variables('name_scriptFile'), parameters('_artifactsLocationSasToken')))]", - "[uri(parameters('_artifactsLocationCoherenceTemplate'), concat('../scripts/', variables('name_scriptELKConfiguration'), parameters('_artifactsLocationSasToken')))]" + "[uri(parameters('_artifactsLocationCoherenceTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameGeneratorscriptFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationCoherenceTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierJavaFile'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationCoherenceTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameValuesTemplate'), parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocationCoherenceTemplate'), concat('../../../../../utilities/custom-hostname-verifier/', variables('name_customHostnameVerifierTest'), parameters('_artifactsLocationSasToken')))]" ] }, "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'),' <<< \"', parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',' ', parameters('adminVMName'),' ',variables('const_wlsHome'),' ',variables('const_wlsDomainPath'),' ', parameters('storageAccountName'), ' ', listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2019-04-01').keys[0].value,' ', variables('const_mountPointPath'),' ', parameters('enableCoherenceWebLocalStorage'), ' ',parameters('enableELK'),' ',variables('const_singleQuote'),parameters('elasticsearchEndpoint'),variables('const_singleQuote'),' ',variables('const_singleQuote'),parameters('elasticsearchUserName'),variables('const_singleQuote'),' ',variables('const_singleQuote'),parameters('elasticsearchPassword'),variables('const_singleQuote'),' ',array.join(parameters('logsToIntegrate')),' ',variables('const_singleQuote'),parameters('logIndex'),variables('const_singleQuote'),' ',variables('name_wlsServerPrefix'),' ',copyIndex(),' ',string(parameters('enableCustomSSL')),' ',base64(parameters('keyVaultCustomIdentityKeyStoreData')),' ',base64(parameters('keyVaultCustomIdentityKeyStorePassPhrase')),' ',base64(parameters('keyVaultCustomIdentityKeyStoreType')),' ',base64(parameters('keyVaultCustomTrustKeyStoreData')),' ',base64(parameters('keyVaultCustomTrustKeyStorePassPhrase')),' ',base64(parameters('keyVaultCustomTrustKeyStoreType')),' ',base64(parameters('keyVaultPrivateKeyAlias')),' ',base64(parameters('keyVaultPrivateKeyPassPhrase')),'\"')]" + "commandToExecute": "[concat('sh',' ',variables('name_scriptFile'),' <<< \"', parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',' ', parameters('adminVMName'),' ',variables('const_wlsHome'),' ',variables('const_wlsDomainPath'),' ', parameters('storageAccountName'), ' ', listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '${azure.apiVersionForStorage}').keys[0].value,' ', variables('const_mountPointPath'),' ', parameters('enableCoherenceWebLocalStorage'), ' ',variables('name_wlsServerPrefix'),' ',copyIndex(),' ',if(parameters('enableDNSConfiguration'),parameters('customDNSNameForAdminServer'),parameters('adminVMName')),' ',parameters('dnsLabelPrefix'),' ',parameters('location'),' ',string(parameters('enableCustomSSL')),' ',base64(parameters('sslCustomIdentityKeyStoreData')),' ',base64(parameters('sslCustomIdentityKeyStorePassPhrase')),' ',parameters('sslCustomIdentityKeyStoreType'),' ',base64(parameters('sslCustomTrustKeyStoreData')),' ',base64(parameters('sslCustomTrustKeyStorePassPhrase')),' ',parameters('sslCustomTrustKeyStoreType'),' ',base64(parameters('sslPrivateKeyAlias')),' ',base64(parameters('sslPrivateKeyPassPhrase')),'\"')]" } } }, { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${dynamic.coherence.end}", "type": "Microsoft.Resources/deployments", "dependsOn": [ diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/dbTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/dbTemplate.json index c8363eeeb..b29bde02a 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/dbTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/dbTemplate.json @@ -8,23 +8,16 @@ "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." } }, - "_artifactsLocationDbTemplate": { - "defaultValue": "[if(contains(parameters('_artifactsLocation'), 'githubusercontent'), parameters('_artifactsLocation'), deployment().properties.templateLink.uri)]", - "type": "string", - "metadata": { - "description": "If we are deploying from the command line, use the passed in _artifactsLocation, otherwise use the default." - } - }, "_artifactsLocationSasToken": { - "defaultValue": "", "type": "securestring", "metadata": { "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." - } + }, + "defaultValue": "" }, "adminVMName": { - "defaultValue": "adminVM", "type": "string", + "defaultValue": "adminVM", "metadata": { "description": "Admin Server hosting VM name." } @@ -36,8 +29,22 @@ "description": "One of the supported database types" } }, + "dbGlobalTranPro": { + "defaultValue": "OnePhaseCommit", + "type": "string", + "metadata": { + "description": "Determines the transaction protocol (global transaction processing behavior) for the data source." + } + }, + "dbIdentity": { + "defaultValue": {}, + "type": "object", + "metadata": { + "description": "Managed identity that has access to the data source." + } + }, "dbPassword": { - "defaultValue": "", + "defaultValue": "[newGuid()]", "type": "securestring", "metadata": { "description": "Password for Database" @@ -57,6 +64,13 @@ "description": "JDBC Connection String" } }, + "enablePswlessConnection": { + "defaultValue": false, + "type": "bool", + "metadata": { + "description": "True to enable passwordless connection." + } + }, "jdbcDataSourceName": { "defaultValue": "", "type": "string", @@ -70,11 +84,33 @@ "description": "Location for all resources." } }, - "wlsUserName": { - "defaultValue": "weblogic", + "managedServerPrefix": { "type": "string", + "defaultValue": "msp", "metadata": { - "description": "Username for your Weblogic domain name" + "description": "Provide managed server prefix name" + } + }, + "managedVMNamePrefix": { + "type": "string", + "metadata": { + "description": "Provide managed VM prefix name" + } + }, + "numberOfManagedApplicationInstances": { + "type": "int", + "defaultValue": 2, + "minValue": 1, + "maxValue": 20, + "metadata": { + "description": "Number of VMs that have been deployed to host managed application server." + } + }, + "wlsDomainName": { + "type": "string", + "defaultValue": "wlsd", + "metadata": { + "description": "Provide Weblogic domain name" } }, "wlsPassword": { @@ -82,121 +118,188 @@ "metadata": { "description": "Password for your Weblogic domain name" } + }, + "wlsUserName": { + "type": "string", + "metadata": { + "description": "Username for your Weblogic domain name" + } } }, "variables": { - "const_wlsAdminPort": "7005", - "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", - "name_scriptFilePrefix": "datasourceConfig-", - "name_scriptFileSuffix-sqlserver": "sqlserver.sh", - "name_scriptFileSuffix-oracle": "oracle.sh", - "name_scriptFileSuffix-postgresql": "postgresql.sh" + "name_dbLinkedTemplateName": "_dbTemplate.json", + "name_dbPswlessTemplateName": "_pswlessDbTemplate.json", + "name_dbUpgradeMySQLDriver": "_installJdbcLibsTemplate.json" }, "resources": [ { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${dynamic.database.start}", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "pswlessDbTemplate", + "condition": "[parameters('enablePswlessConnection')]", "properties": { "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(parameters('adminVMName'),'/newuserscript')]", - "location": "[parameters('location')]", - "properties": { - "publisher": "Microsoft.Azure.Extensions", - "type": "CustomScript", - "typeHandlerVersion": "2.0", - "autoUpgradeMinorVersion": true, - "settings": { - "fileUris": [ - "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-sqlserver'), parameters('_artifactsLocationSasToken')))]", - "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-oracle'), parameters('_artifactsLocationSasToken')))]", - "[uri(parameters('_artifactsLocationDbTemplate'), concat('../scripts/', variables('name_scriptFilePrefix'), variables('name_scriptFileSuffix-postgresql'), parameters('_artifactsLocationSasToken')))]" - ] + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_dbPswlessTemplateName')))]", + "contentVersion": "1.0.0.0" }, - "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptFilePrefix'),parameters('databaseType'),'.sh <<< \"',variables('const_wlsHome'),' ',parameters('adminVMName'),' ',variables('const_wlsAdminPort'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',parameters('jdbcDataSourceName'),' ',parameters('dsConnectionURL'),' ',parameters('dbUser'),' ',parameters('dbPassword'),'\"')]" - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${dynamic.database.end}", - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" - ], - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${database.oracle}", - "condition": "[if(contains(parameters('databaseType'), 'oracle'), bool('true'), bool('false'))]", - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" - ], - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] + "parameters": { + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + }, + "adminVMName": { + "value": "[parameters('adminVMName')]" + }, + "databaseType": { + "value": "[parameters('databaseType')]" + }, + "dbGlobalTranPro": { + "value": "[parameters('dbGlobalTranPro')]" + }, + "dbIdentity": { + "value": "[parameters('dbIdentity')]" + }, + "dbUser": { + "value": "[parameters('dbUser')]" + }, + "dsConnectionURL": { + "value": "[parameters('dsConnectionURL')]" + }, + "jdbcDataSourceName": { + "value": "[parameters('jdbcDataSourceName')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "managedServerPrefix": { + "value": "[parameters('managedServerPrefix')]" + }, + "managedVMNamePrefix": { + "value": "[parameters('managedVMNamePrefix')]" + }, + "numberOfManagedApplicationInstances": { + "value": "[parameters('numberOfManagedApplicationInstances')]" + }, + "wlsDomainName": { + "value": "[parameters('wlsDomainName')]" + }, + "wlsPassword": { + "value": "[parameters('wlsPassword')]" + }, + "wlsUserName": { + "value": "[parameters('wlsUserName')]" + } } } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${database.postgresql}", - "condition": "[if(contains(parameters('databaseType'), 'postgresql'), bool('true'), bool('false'))]", - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" - ], + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "upgradeMySQLJdbcDriverTemplate", + "condition": "[and(not(parameters('enablePswlessConnection')), equals(parameters('databaseType'),'mysql'))]", "properties": { "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_dbUpgradeMySQLDriver')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + }, + "adminVMName": { + "value": "[parameters('adminVMName')]" + }, + "databaseType": { + "value": "[parameters('databaseType')]" + }, + "enablePswlessConnection": { + "value": "[parameters('enablePswlessConnection')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "managedServerPrefix": { + "value": "[parameters('managedServerPrefix')]" + }, + "managedVMNamePrefix": { + "value": "[parameters('managedVMNamePrefix')]" + }, + "numberOfManagedApplicationInstances": { + "value": "[parameters('numberOfManagedApplicationInstances')]" + }, + "wlsDomainName": { + "value": "[parameters('wlsDomainName')]" + }, + "wlsPassword": { + "value": "[parameters('wlsPassword')]" + }, + "wlsUserName": { + "value": "[parameters('wlsUserName')]" + } } } }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${database.sqlserver}", - "condition": "[if(contains(parameters('databaseType'), 'sqlserver'), bool('true'), bool('false'))]", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "passwordDatasourceDeployment", + "condition": "[not(parameters('enablePswlessConnection'))]", "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" + "[resourceId('Microsoft.Resources/deployments', 'upgradeMySQLJdbcDriverTemplate')]" ], "properties": { "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] + "templateLink": { + "uri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('name_dbLinkedTemplateName')))]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + }, + "adminVMName": { + "value": "[parameters('adminVMName')]" + }, + "databaseType": { + "value": "[parameters('databaseType')]" + }, + "dbGlobalTranPro": { + "value": "[parameters('dbGlobalTranPro')]" + }, + "dbPassword": { + "value": "[parameters('dbPassword')]" + }, + "dbUser": { + "value": "[parameters('dbUser')]" + }, + "dsConnectionURL": { + "value": "[parameters('dsConnectionURL')]" + }, + "enablePswlessConnection": { + "value": "[parameters('enablePswlessConnection')]" + }, + "jdbcDataSourceName": { + "value": "[parameters('jdbcDataSourceName')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "wlsPassword": { + "value": "[parameters('wlsPassword')]" + }, + "wlsUserName": { + "value": "[parameters('wlsUserName')]" + } } } } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/dnszonesTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/dnszonesTemplate.json index 2a383c2c1..f40e26e1e 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/dnszonesTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/dnszonesTemplate.json @@ -15,6 +15,12 @@ "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." } }, + "_globalResourceNameSuffix": { + "type": "string", + "metadata": { + "description": "A suffix to be appended to all resources created by this template." + } + }, "dnszonesARecordSetNames": { "type": "array", "defaultValue": [], @@ -57,12 +63,6 @@ "description": "If true, update A records in the existing DNS Zone, otherwise, create a new DNS Zone and ." } }, - "identity": { - "type": "Object", - "metadata": { - "description": "Managed identity to be used for the deployment script. Currently, only user-assigned MSI is supported." - } - }, "location": { "type": "string", "metadata": { @@ -105,7 +105,7 @@ }, "resources": [ { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${cluster.dns.start}", "type": "Microsoft.Resources/deployments", "properties": { @@ -119,7 +119,7 @@ } }, { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "type": "Microsoft.Resources/deployments", "name": "createDNSZone", "condition": "[not(parameters('hasDNSZones'))]", @@ -155,7 +155,7 @@ } }, { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "type": "Microsoft.Resources/deployments", "name": "updateDNSZone", "condition": "[parameters('hasDNSZones')]", @@ -172,6 +172,9 @@ "_artifactsLocationSasToken": { "value": "[parameters('_artifactsLocationSasToken')]" }, + "_globalResourceNameSuffix": { + "value": "[parameters('_globalResourceNameSuffix')]" + }, "dnszonesARecordSetNames": { "value": "[parameters('dnszonesARecordSetNames')]" }, @@ -184,9 +187,6 @@ "dnszoneName": { "value": "[parameters('dnszoneName')]" }, - "identity": { - "value": "[parameters('identity')]" - }, "location": { "value": "[parameters('location')]" }, @@ -206,7 +206,7 @@ } }, { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${cluster.dns.end}", "type": "Microsoft.Resources/deployments", "properties": { diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/elkNestedTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/elkNestedTemplate.json deleted file mode 100644 index 63f026f8d..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/elkNestedTemplate.json +++ /dev/null @@ -1,270 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "_artifactsLocation": { - "type": "string", - "metadata": { - "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." - } - }, - "_artifactsLocationELKTemplate": { - "defaultValue": "[if(contains(parameters('_artifactsLocation'), 'githubusercontent'), parameters('_artifactsLocation'), deployment().properties.templateLink.uri)]", - "type": "string", - "metadata": { - "description": "If we are deploying from the command line, use the passed in _artifactsLocation, otherwise use the default." - } - }, - "_artifactsLocationSasToken": { - "defaultValue": "", - "type": "securestring", - "metadata": { - "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." - } - }, - "adminVMName": { - "type": "string", - "defaultValue": "adminVM", - "metadata": { - "description": "Admin Server hosting VM name." - } - }, - "elasticsearchEndpoint": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Endpoint of the Elasticsearch instance." - } - }, - "elasticsearchPassword": { - "type": "securestring", - "defaultValue": "[newGuid()]", - "metadata": { - "description": "The credentials to distibute message with REST API to Elasticsearch instance." - } - }, - "elasticsearchUserName": { - "type": "string", - "defaultValue": "elastic", - "metadata": { - "description": "The credentials to distibute message with REST API to Elasticsearch instance." - } - }, - "guidValue": { - "type": "string", - "defaultValue": "[newGuid()]" - }, - "location": { - "type": "string", - "metadata": { - "description": "Location for all resources." - } - }, - "logsToIntegrate": { - "type": "array", - "defaultValue": [ "HTTPAccessLog", "ServerLog", "DomainLog", "DataSourceLog", "StandardErrorAndOutput", "NodeManagerLog" ], - "allowedValues": [ "HTTPAccessLog", "ServerLog", "DomainLog", "DataSourceLog", "StandardErrorAndOutput", "NodeManagerLog" ], - "metadata": { - "description": "Specify the expeted logs to integrate, you must input at least one log." - } - }, - "managedServerPrefix": { - "type": "string", - "defaultValue": "msp", - "metadata": { - "description": "Provide managed server prefix name" - } - }, - "maxDynamicClusterSize": { - "defaultValue": 10, - "type": "int", - "metadata": { - "description": "Maximum Number of Managed Servers allowed to be configured in the Dynamic Cluster" - } - }, - "numberOfManagedCacheInstances": { - "type": "int", - "defaultValue": 0, - "minValue": 0, - "maxValue": 20, - "metadata": { - "description": "Number of VMs that have been deployed to host managed cache server, please set the value if your cluster is Coherence cluster." - } - }, - "numberOfManagedApplicationInstances": { - "type": "int", - "defaultValue": 2, - "minValue": 1, - "maxValue": 20, - "metadata": { - "description": "Number of VMs that have been deployed to host managed application server." - } - }, - "wlsDomainName": { - "type": "string", - "defaultValue": "wlsd", - "metadata": { - "description": "Provide Weblogic domain name" - } - }, - "wlsPassword": { - "type": "securestring", - "metadata": { - "description": "Password for your Weblogic domain name" - } - }, - "wlsUserName": { - "type": "string", - "metadata": { - "description": "Username for your Weblogic domain name" - } - } - }, - "variables": { - "const_adminServerName": "admin", - "const_logIndex": "[concat('azure-weblogic-dynamic-cluster-', parameters('guidValue'))]", - "const_managedCacheVMPrefix": "[concat(parameters('managedServerPrefix'),'StorageVM')]", - "const_managedVMPrefix": "[concat(parameters('managedServerPrefix'),'VM')]", - "const_wlsAdminPort": "7005", - "const_wlsDomainPath": "[concat('/u01/domains/', parameters('wlsDomainName'))]", - "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", - "name_scriptELKConfiguration": "elkIntegrationForDynamicCluster.sh" - }, - "functions": [ - { - "namespace": "array", - "members": { - "join": { - "parameters": [ - { - "name": "items", - "type": "array" - } - ], - "output": { - "type": "string", - "value": "[replace(replace(replace(string(parameters('items')), '[\"', ''), '\"]', ''), '\",\"', ',')]" - } - } - } - } - ], - "resources": [ - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${dynamic.elk.start}", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(parameters('adminVMName'),'/newuserscript')]", - "location": "[parameters('location')]", - "properties": { - "publisher": "Microsoft.Azure.Extensions", - "type": "CustomScript", - "typeHandlerVersion": "2.0", - "autoUpgradeMinorVersion": true, - "settings": { - "fileUris": [ - "[uri(parameters('_artifactsLocationELKTemplate'), concat('../scripts/', variables('name_scriptELKConfiguration'), parameters('_artifactsLocationSasToken')))]" - ] - }, - "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptELKConfiguration'),' <<< \"', variables('const_wlsHome'), ' ', concat(parameters('adminVMName'), ':', variables('const_wlsAdminPort')), ' ' ,parameters('managedServerPrefix'), ' ', parameters('wlsUserName'), ' ', parameters('wlsPassword'), ' ', variables('const_adminServerName'), ' ', parameters('elasticsearchEndpoint'),' ', parameters('elasticsearchUserName'),' ', parameters('elasticsearchPassword'), ' ', parameters('wlsDomainName'),' ', variables('const_wlsDomainPath'),' ', array.join(parameters('logsToIntegrate')), ' ',0, ' ', variables('const_logIndex'), ' ', parameters('maxDynamicClusterSize'),'\"')]" - } - } - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(variables('const_managedVMPrefix'), copyIndex(1),'/newuserscript')]", - "location": "[parameters('location')]", - "copy": { - "name": "appVirtualMachineExtensionLoop", - "count": "[parameters('numberOfManagedApplicationInstances')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" - ], - "properties": { - "publisher": "Microsoft.Azure.Extensions", - "type": "CustomScript", - "typeHandlerVersion": "2.0", - "autoUpgradeMinorVersion": true, - "settings": { - "fileUris": [ - "[uri(parameters('_artifactsLocationELKTemplate'), concat('../scripts/', variables('name_scriptELKConfiguration'), parameters('_artifactsLocationSasToken')))]" - ] - }, - "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptELKConfiguration'),' <<< \"', variables('const_wlsHome'), ' ', concat(parameters('adminVMName'), ':', variables('const_wlsAdminPort')), ' ' ,parameters('managedServerPrefix'), ' ', parameters('wlsUserName'), ' ', parameters('wlsPassword'), ' ', variables('const_adminServerName'), ' ', parameters('elasticsearchEndpoint'),' ', parameters('elasticsearchUserName'),' ', parameters('elasticsearchPassword'), ' ', parameters('wlsDomainName'),' ', variables('const_wlsDomainPath'),' ', array.join(parameters('logsToIntegrate')), ' ',copyIndex(1), ' ', variables('const_logIndex'), ' ', parameters('maxDynamicClusterSize'),'\"')]" - } - } - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", - "name": "[concat(variables('const_managedCacheVMPrefix'), copyIndex(1),'/newuserscript')]", - "location": "[parameters('location')]", - "copy": { - "name": "cacheVirtualMachineExtensionLoop", - "count": "[parameters('numberOfManagedCacheInstances')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" - ], - "properties": { - "publisher": "Microsoft.Azure.Extensions", - "type": "CustomScript", - "typeHandlerVersion": "2.0", - "autoUpgradeMinorVersion": true, - "settings": { - "fileUris": [ - "[uri(parameters('_artifactsLocationELKTemplate'), concat('../scripts/', variables('name_scriptELKConfiguration'), parameters('_artifactsLocationSasToken')))]" - ] - }, - "protectedSettings": { - "commandToExecute": "[concat('sh',' ',variables('name_scriptELKConfiguration'),' <<< \"', variables('const_wlsHome'), ' ', concat(parameters('adminVMName'), ':', variables('const_wlsAdminPort')), ' ' ,concat(parameters('managedServerPrefix'), 'Storage'), ' ', parameters('wlsUserName'), ' ', parameters('wlsPassword'), ' ', variables('const_adminServerName'), ' ', parameters('elasticsearchEndpoint'),' ', parameters('elasticsearchUserName'),' ', parameters('elasticsearchPassword'), ' ', parameters('wlsDomainName'),' ', variables('const_wlsDomainPath'),' ', array.join(parameters('logsToIntegrate')), ' ',copyIndex(1), ' ', variables('const_logIndex'), ' ', parameters('maxDynamicClusterSize'),'\"')]" - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", - "name": "${dynamic.elk.end}", - "dependsOn": [ - "appVirtualMachineExtensionLoop", - "cacheVirtualMachineExtensionLoop" - ], - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - ] - } - } - } - ], - "outputs": { - "artifactsLocationPassedIn": { - "type": "string", - "value": "[parameters('_artifactsLocation')]" - }, - "logIndex": { - "type": "string", - "value": "[variables('const_logIndex')]" - } - } -} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/nsgNestedTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/nsgNestedTemplate.json index 7d107cd3f..e74edab2b 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/nsgNestedTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/nsgNestedTemplate.json @@ -29,7 +29,7 @@ "type": "Microsoft.Network/networkSecurityGroups/securityRules", "name": "[concat(parameters('networkSecurityGroupName'),'/','WebLogicAdminPortsAllowed')]", "condition": "[not(parameters('denyPublicTrafficForAdminServer'))]", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForNetworkSecurityGroups}", "properties": { "protocol": "TCP", "sourcePortRange": "*", @@ -48,7 +48,7 @@ "type": "Microsoft.Network/networkSecurityGroups/securityRules", "name": "[concat(parameters('networkSecurityGroupName'),'/','WebLogicAdminPortsDenied')]", "condition": "[parameters('denyPublicTrafficForAdminServer')]", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForNetworkSecurityGroups}", "properties": { "protocol": "*", "sourcePortRange": "*", @@ -67,7 +67,7 @@ "type": "Microsoft.Network/networkSecurityGroups/securityRules", "name": "[concat(parameters('networkSecurityGroupName'),'/','WebLogiManagedPortsAllowed')]", "condition": "[and(not(parameters('denyPublicTrafficForManagedServer')), parameters('enableOHS'))]", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForNetworkSecurityGroups}", "properties": { "protocol": "*", "sourcePortRange": "*", @@ -85,7 +85,7 @@ "type": "Microsoft.Network/networkSecurityGroups/securityRules", "name": "[concat(parameters('networkSecurityGroupName'),'/','WebLogiManagedPortsDenied')]", "condition": "[and(parameters('denyPublicTrafficForManagedServer'), parameters('enableOHS'))]", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForNetworkSecurityGroups}", "properties": { "protocol": "*", "sourcePortRange": "*", diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/ohsNestedTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/ohsNestedTemplate.json index d6981d2cc..d1c110e96 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/ohsNestedTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/ohsNestedTemplate.json @@ -78,6 +78,12 @@ "description": "Location for all resources." } }, + "nsgName": { + "type": "string", + "metadata": { + "description": "Name of the Network Security Group." + } + }, "ohsComponentName": { "type": "string", "metadata": { @@ -105,13 +111,13 @@ "ohsSSLKeystoreData": { "type": "securestring", "metadata": { - "description": "The name of the secret in the specified KeyVault whose value is the SSL Certificate Data" + "description": "The SSL Certificate Data" } }, "ohsSSLKeystorePassword": { "type": "securestring", "metadata": { - "description": "The name of the secret in the specified KeyVault whose value is the password for the SSL Certificate" + "description": "The password for the SSL Certificate" } }, "ohsSkuUrnVersion": { @@ -156,13 +162,38 @@ "description": "Name of storage account. One storage account can store 20 vitual machines with 2 VHDs of 500 IOPS." } }, + "subnetName": { + "type": "string", + "defaultValue": "wls-subnet", + "metadata": { + "description": "Name of the existing or new Subnet" + } + }, + "virtualNetworkNewOrExisting": { + "type": "string", + "defaultValue": "new", + "allowedValues": [ + "new", + "existing" + ], + "metadata": { + "description": "Specify whether to create a new or existing virtual network for the VM." + } + }, + "virtualNetworkResourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "Resource group of Virtual network" + } + }, "virtualNetworkName": { "type": "string", "metadata": { "description": "virtual network name." } }, - "vmSizeSelect": { + "vmSize": { "type": "string", "defaultValue": "Standard_A3", "metadata": { @@ -197,23 +228,23 @@ } }, "const_publicIPAddressType": "Dynamic", - "const_vmSize": "[parameters('vmSizeSelect')]", + "const_vmSize": "[parameters('vmSize')]", "name_linuxImageOfferSKU": "[variables('name_ohsSkuUrnVersion')[1]]", "name_linuxImageVersion": "[variables('name_ohsSkuUrnVersion')[2]]", - "name_networkSecurityGroup": "[concat(parameters('dnsLabelPrefix'), '-nsg')]", "name_nic": "_NIC", "name_ohsSkuUrnVersion": "[split(parameters('ohsSkuUrnVersion'), ';')]", "name_outputOHSHost": "[concat(parameters('ohsVMName'),variables('name_publicIPAddress'))]", "name_publicIPAddress": "_PublicIP", "name_scriptFile": "setupOHS.sh", - "name_subnet": "Subnet", - "ref_subnet": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), variables('name_subnet'))]" + "name_subnet": "[parameters('subnetName')]", + "ref_subnet": "[resourceId(parameters('virtualNetworkResourceGroupName'), 'Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), variables('name_subnet'))]" }, "resources": [ { "type": "Microsoft.Network/networkSecurityGroups/securityRules", - "name": "[concat( variables('name_networkSecurityGroup'),'/','OHSPorts')]", - "apiVersion": "${azure.apiVersion}", + "condition": "[equals(parameters('virtualNetworkNewOrExisting'), 'new')]", + "name": "[concat(parameters('nsgName'),'/','OHSPorts')]", + "apiVersion": "${azure.apiVersionForNetworkSecurityGroups}", "properties": { "protocol": "TCP", "sourcePortRange": "*", @@ -226,8 +257,8 @@ } }, { + "apiVersion": "${azure.apiVersionForPublicIPAddresses}", "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "${azure.apiVersion}", "name": "[concat(parameters('ohsVMName'),variables('name_publicIPAddress'))]", "location": "[parameters('location')]", "properties": { @@ -238,14 +269,14 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualNetworks}", "type": "Microsoft.Network/virtualNetworks/subnets", - "apiVersion": "${azure.apiVersion}", "name": "[concat(parameters('virtualNetworkName'), '/', variables('name_subnet'))]", "condition": "[and(empty(parameters('virtualNetworkName')), empty(variables('name_subnet')))]" }, { + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "${azure.apiVersion}", "name": "[concat(parameters('ohsVMName'), variables('name_nic'))]", "location": "[parameters('location')]", "dependsOn": [ @@ -272,8 +303,8 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "${azure.apiVersion}", "name": "[parameters('ohsVMName')]", "location": "[parameters('location')]", "dependsOn": [ @@ -301,17 +332,7 @@ "managedDisk": { "storageAccountType": "StandardSSD_LRS" } - }, - "dataDisks": [ - { - "lun": 0, - "createOption": "FromImage", - "diskSizeGB": 900, - "managedDisk": { - "storageAccountType": "StandardSSD_LRS" - } - } - ] + } }, "networkProfile": { "networkInterfaces": [ @@ -323,7 +344,7 @@ "diagnosticsProfile": { "bootDiagnostics": { "enabled": true, - "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', parameters('storageAccountName')), '${azure.apiVersion2}').primaryEndpoints.blob]" + "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', parameters('storageAccountName')), '${azure.apiVersionForStorage}').primaryEndpoints.blob]" } } }, @@ -334,9 +355,9 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines/extensions", "name": "[concat(parameters('ohsVMName'),'/newuserscript')]", - "apiVersion": "${azure.apiVersion}", "location": "[parameters('location')]", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachines/', parameters('ohsVMName'))]" @@ -364,15 +385,15 @@ }, "ohsHostName": { "type": "string", - "value": "[reference(variables('name_outputOHSHost'), '${azure.apiVersion}').dnsSettings.fqdn]" + "value": "[reference(variables('name_outputOHSHost'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn]" }, "ohsAccessURL": { "type": "string", - "value": "[concat('http://',reference(variables('name_outputOHSHost'), '${azure.apiVersion}').dnsSettings.fqdn,':',parameters('ohshttpPort'))]" + "value": "[uri(format('http://{0}:{1}',reference(variables('name_outputOHSHost'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn,parameters('ohshttpPort')),'')]" }, "ohsSecureAccessURL": { "type": "string", - "value": "[concat('https://',reference(variables('name_outputOHSHost'), '${azure.apiVersion}').dnsSettings.fqdn,':',parameters('ohshttpsPort'))]" + "value": "[uri(format('https://{0}:{1}',reference(variables('name_outputOHSHost'), '${azure.apiVersionForPublicIPAddresses}').dnsSettings.fqdn,parameters('ohshttpsPort')),'')]" } } } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/postDeploymentTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/postDeploymentTemplate.json new file mode 100644 index 000000000..37ed87e2f --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/postDeploymentTemplate.json @@ -0,0 +1,99 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "metadata": { + "description": "Location for all resources." + } + }, + "_globalResourceNameSuffix": { + "type": "string", + "metadata": { + "description": "A unique suffix that was specified during the deployment of the solution template." + } + }, + "const_guidTag" :{ + "type": "string", + "metadata": { + "description": "A unique tag for resources." + } + }, + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." + } + }, + "_artifactsLocationAdminTemplate": { + "defaultValue": "[if(contains(parameters('_artifactsLocation'), 'githubusercontent'), parameters('_artifactsLocation'), deployment().properties.templateLink.uri)]", + "type": "string", + "metadata": { + "description": "If we are deploying from the command line, use the passed in _artifactsLocation, otherwise use the default." + } + }, + "_artifactsLocationSasToken": { + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." + } + }, + "userAssignedIdentityResourceId":{ + "type": "string", + "metadata": { + "Description": "UserAssigned Identity" + } + }, + "utcValue": { + "type": "string", + "defaultValue": "[utcNow()]" + } + }, + "variables": { + "name_postDeploymentscriptFile": "postDeploymentScript.sh" + }, + "resources": [ + { + "type": "Microsoft.Resources/deploymentScripts", + "apiVersion": "${azure.apiVersionForDeploymentScript}", + "name": "[concat('postdeployscript-', parameters('_globalResourceNameSuffix'))]", + "kind": "AzureCLI", + "location": "[parameters('location')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[parameters('userAssignedIdentityResourceId')]": {} + } + }, + "properties": { + "forceUpdateTag": "[parameters('utcValue')]", + "azCliVersion": "2.9.1", + "timeout": "PT30M", + "cleanupPreference": "OnSuccess", + "retentionInterval": "P1D", + "primaryScriptUri": "[uri(parameters('_artifactsLocationAdminTemplate'), concat('../scripts/', variables('name_postDeploymentscriptFile'), parameters('_artifactsLocationSasToken')))]", + "environmentVariables": [ + { + "name": "MANAGED_IDENTITY_ID", + "value": "[parameters('userAssignedIdentityResourceId')]" + }, + { + "name": "RESOURCE_GROUP_NAME", + "value": "[resourceGroup().name]" + }, + { + "name": "GUID_TAG", + "value": "[parameters('const_guidTag')]" + } + ] + } + } + ], + "outputs": { + "userAssignedIdentityResource": { + "type": "string", + "value": "[parameters('userAssignedIdentityResourceId')]" + } + } +} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/postDeploymentUAMIRolesTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/postDeploymentUAMIRolesTemplate.json new file mode 100644 index 000000000..359c76050 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/nestedtemplates/postDeploymentUAMIRolesTemplate.json @@ -0,0 +1,101 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "metadata": { + "description": "Location for all resources." + } + }, + "_globalResourceNameSuffix": { + "type": "string", + "metadata": { + "description": "A unique suffix that was specified during the deployment of the solution template." + } + }, + "roleAssignmentNameSeed": { + "type": "string", + "defaultValue": "[guid(subscription().id, parameters('_globalResourceNameSuffix'))]", + "metadata": { + "description": "A unique string used to generate the role assignment name. Defaults to a unique GUID based on the deployment context." + } + } + }, + "variables": { + "const_roleDefinitionIdOfContributor": "b24988ac-6180-42a0-ab88-20f7382dd24c", + "name_postDeploymentScriptUserDefinedManagedIdentity": "[concat('post-deployment-user-defined-managed-identity', parameters('_globalResourceNameSuffix'))]", + "name_postDeploymentScriptRoleAssignment": "[concat('post-deployment-user-defined-role-assignment', parameters('_globalResourceNameSuffix'))]" + }, + "resources": [ + { + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "${azure.apiVersionForIdentity}", + "name": "[variables('name_postDeploymentScriptUserDefinedManagedIdentity')]", + "location": "[parameters('location')]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "[variables('name_postDeploymentScriptRoleAssignment')]", + "location": "[parameters('location')]", + "subscriptionId": "[subscription().subscriptionId]", + "dependsOn": [ + "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('name_postDeploymentScriptUserDefinedManagedIdentity'))]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "innerPrincipalId": { + "type": "string" + }, + "innerRoleDefinitionId": { + "type": "string" + }, + "innerRoleAssignmentNameSeed": { + "type": "string" + } + }, + "variables": { + "roleAssignmentGuid": "[guid(parameters('innerRoleAssignmentNameSeed'))]" + }, + "resources": [ + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "${azure.apiVersionForRoleAssignment}", + "name": "[variables('roleAssignmentGuid')]", + "properties": { + "roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', parameters('innerRoleDefinitionId'))]", + "principalId": "[parameters('innerPrincipalId')]", + "principalType": "ServicePrincipal" + } + } + ] + }, + "parameters": { + "innerPrincipalId": { + "value": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities',variables('name_postDeploymentScriptUserDefinedManagedIdentity'))).principalId]" + }, + "innerRoleDefinitionId": { + "value": "[variables('const_roleDefinitionIdOfContributor')]" + }, + "innerRoleAssignmentNameSeed": { + "value": "[parameters('roleAssignmentNameSeed')]" + } + } + } + } + ], + "outputs": { + "uamidForPostDeployment": { + "type": "string", + "value": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('name_postDeploymentScriptUserDefinedManagedIdentity'))]" + } + } +} \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/resources/README.md b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/resources/README.md index 2f52022e0..a6c15c46c 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/resources/README.md +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/resources/README.md @@ -1,10 +1,15 @@ + + # What is this stuff? Content that goes into the "Marketplace" tab of the offer. See [the Marketplace documentation](https://docs.microsoft.com/en-us/azure/marketplace/cloud-partner-portal/virtual-machine/cpp-marketplace-tab) for details. -When submitting the offer, use content from [https://github.com/wls-eng/arm-oraclelinux-wls/tree/master/arm-oraclelinux-wls/src/main/resources](this directory), but apply the changes in this file on top. +When submitting the offer, use content from [https://github.com/oracle/weblogic-azure/tree/main/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources](this directory), but apply the changes in this file on top. ## Offer Settings @@ -18,7 +23,7 @@ oracle Name -Oracle WebLogic Server 12.2.1.3 Dynamic Cluster +Oracle WebLogic Server Dynamic Cluster ## SKU Details @@ -28,7 +33,7 @@ SKU ID Title -Oracle WebLogic Server 12.2.1.3 Dynamic Cluster +Oracle WebLogic Server Dynamic Cluster Summary @@ -36,7 +41,7 @@ Provisions an n-node Oracle WebLogic Server Dynamic Cluster Description -Provisions an n-node Oracle WebLogic Server dynamic cluster on Oracle Linux 7.6 +Provisions an n-node Oracle WebLogic Server dynamic cluster on Oracle Linux 9.1, 8.7 and 7.6 SKU Type @@ -54,7 +59,7 @@ No Title -Oracle WebLogic Server 12.2.1.3 Dynamic Cluster +Oracle WebLogic Server Dynamic Cluster Summary @@ -62,11 +67,11 @@ Provisions an n-node Oracle WebLogic Server Cluster Long Summary -Provisions an n-node Oracle WebLogic Server cluster on Oracle Linux 7.6 +Provisions an n-node Oracle WebLogic Server cluster on Oracle Linux 9.1, 8.7 and 7.6 Description -[description.html](https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/master/arm-oraclelinux-wls/src/main/resources/description.html) +[description.html](https://raw.githubusercontent.com/oracle/weblogic-azure/main/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/description.html) Offer available to Microsoft CSP Reseller channel? * diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/aadIntegration.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/aadIntegration.sh deleted file mode 100644 index 84c36709e..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/aadIntegration.sh +++ /dev/null @@ -1,491 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# -#Function to output message to StdErr -function echo_stderr() -{ - echo "$@" >&2 -} - -#Function to display usage message -function usage() -{ - echo_stderr "./aadIntegration.sh <<< \"\"" -} - -function validateInput() -{ - if [[ -z "$wlsUserName" || -z "$wlsPassword" ]] - then - echo_stderr "wlsUserName or wlsPassword is required. " - exit 1 - fi - - if [ -z "$wlsDomainName" ]; - then - echo_stderr "wlsDomainName is required. " - fi - - if [ -z "$adProviderName" ]; - then - echo_stderr "adProviderName is required. " - fi - - if [ -z "$adPrincipal" ]; - then - echo_stderr "adPrincipal is required. " - fi - - if [ -z "$adPassword" ]; - then - echo_stderr "adPassword is required. " - fi - - if [ -z "$adServerHost" ]; - then - echo_stderr "adServerHost is required. " - fi - - if [ -z "$adServerPort" ]; - then - echo_stderr "adServerPort is required. " - fi - - if [ -z "$adGroupBaseDN" ]; - then - echo_stderr "adGroupBaseDN is required. " - fi - - if [ -z "$adUserBaseDN" ]; - then - echo_stderr "adUserBaseDN is required. " - fi - - if [ -z "$oracleHome" ]; - then - echo_stderr "oracleHome is required. " - fi - - if [ -z "$wlsAdminHost" ]; - then - echo_stderr "wlsAdminHost is required. " - fi - - if [ -z "$wlsAdminPort" ]; - then - echo_stderr "wlsAdminPort is required. " - fi - - if [ -z "$wlsADSSLCer" ]; - then - echo_stderr "wlsADSSLCer is required. " - fi - - if [ -z "$wlsLDAPPublicIP" ]; - then - echo_stderr "wlsLDAPPublicIP is required. " - fi - - if [ -z "$wlsAdminServerName" ]; - then - echo_stderr "wlsAdminServerName is required. " - fi - - if [ -z "$wlsDomainPath" ]; - then - echo_stderr "wlsDomainPath is required. " - fi - - if [ -z "$vmIndex" ]; - then - echo_stderr "vmIndex is required. " - fi - - - if [ "${isCustomSSLEnabled,,}" != "true" ]; - then - echo_stderr "Custom SSL value is not provided. Defaulting to false" - isCustomSSLEnabled="false" - else - if [ -z "$customTrustKeyStorePassPhrase" ]; - then - echo "customTrustKeyStorePassPhrase is required " - exit 1 - fi - fi -} - -function createAADProvider_model() -{ - cat <${SCRIPT_PATH}/configure-active-directory.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') -try: - edit("$wlsAdminServerName") - startEdit() - cd('/') - # Configure DefaultAuthenticator. - cd('/SecurityConfiguration/' + '${wlsDomainName}' + '/Realms/myrealm/AuthenticationProviders/DefaultAuthenticator') - cmo.setControlFlag('SUFFICIENT') - - # Configure Active Directory. - cd('/SecurityConfiguration/' + '${wlsDomainName}' + '/Realms/myrealm') - cmo.createAuthenticationProvider('${adProviderName}', 'weblogic.security.providers.authentication.ActiveDirectoryAuthenticator') - - cd('/SecurityConfiguration/' + '${wlsDomainName}' + '/Realms/myrealm/AuthenticationProviders/' + '${adProviderName}') - cmo.setControlFlag('OPTIONAL') - - cd('/SecurityConfiguration/' + '${wlsDomainName}' + '/Realms/myrealm') - set('AuthenticationProviders',jarray.array([ObjectName('Security:Name=myrealm' + '${adProviderName}'), - ObjectName('Security:Name=myrealmDefaultAuthenticator'), - ObjectName('Security:Name=myrealmDefaultIdentityAsserter')], ObjectName)) - - - cd('/SecurityConfiguration/' + '${wlsDomainName}' + '/Realms/myrealm/AuthenticationProviders/' + '${adProviderName}') - cmo.setControlFlag('SUFFICIENT') - cmo.setUserNameAttribute('${LDAP_USER_NAME}') - cmo.setUserFromNameFilter('${LDAP_USER_FROM_NAME_FILTER}') - cmo.setPrincipal('${adPrincipal}') - cmo.setHost('${adServerHost}') - set('Credential', '${adPassword}') - cmo.setGroupBaseDN('${adGroupBaseDN}') - cmo.setUserBaseDN('${adUserBaseDN}') - cmo.setPort(int('${adServerPort}')) - cmo.setSSLEnabled(true) - - # for performance tuning - cmo.setMaxGroupMembershipSearchLevel(1) - cmo.setGroupMembershipSearching('limited') - cmo.setUseTokenGroupsForGroupMembershipLookup(true) - cmo.setResultsTimeLimit(300) - cmo.setConnectionRetryLimit(5) - cmo.setConnectTimeout(120) - cmo.setCacheTTL(300) - cmo.setConnectionPoolSize(60) - cmo.setCacheSize(4000) - cmo.setGroupHierarchyCacheTTL(300) - cmo.setEnableSIDtoGroupLookupCaching(true) - - save() - resolve() - activate() -except: - stopEdit('y') - sys.exit(1) - -destroyEditSession("$wlsAdminServerName",force = true) -disconnect() -sys.exit(0) -EOF -} - -function createSSL_model() -{ - cat <${SCRIPT_PATH}/configure-ssl.py -# Connect to the AdminServer. -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') -shutdown('$WLS_CLUSTER_NAME', 'Cluster') -print "Ignore host name verification in admin server." -try: - edit('$wlsAdminServerName') - startEdit() - cd('/Servers/${wlsAdminServerName}/SSL/${wlsAdminServerName}') - cmo.setHostnameVerificationIgnored(true) - print "Ignore host name verification in cluster." - - cd('/ServerTemplates/${WLS_DYNAMIC_SERVER_TEMPLATE}/SSL/${WLS_DYNAMIC_SERVER_TEMPLATE}') - cmo.setHostnameVerificationIgnored(true) -EOF - - . $oracleHome/oracle_common/common/bin/setWlstEnv.sh - ${JAVA_HOME}/bin/java -version 2>&1 | grep -e "1[.]8[.][0-9]*_" > /dev/null - javaStatus=$? - if [ "${javaStatus}" == "0" ]; then - cat <>${SCRIPT_PATH}/configure-ssl.py - cd('/ServerTemplates/${WLS_DYNAMIC_SERVER_TEMPLATE}//ServerStart/${WLS_DYNAMIC_SERVER_TEMPLATE}') - arguments = cmo.getArguments() - if(str(arguments) == 'None'): - arguments = '${JAVA_OPTIONS_TLS_V12}' - else: - arguments = str(arguments) + ' ' + '${JAVA_OPTIONS_TLS_V12}' - cmo.setArguments(arguments) -EOF - fi - -cat <>${SCRIPT_PATH}/configure-ssl.py - save() - resolve() - activate() -except: - stopEdit('y') - dumpStack() - sys.exit(1) -destroyEditSession("$wlsAdminServerName") - -try: - start('$WLS_CLUSTER_NAME', 'Cluster') -except: - dumpStack() - -disconnect() -EOF -} - -function mapLDAPHostWithPublicIP() -{ - echo "map LDAP host with pubilc IP" - - # remove existing ip address for the same host - sudo sed -i '/${adServerHost}/d' /etc/hosts - sudo echo "${wlsLDAPPublicIP} ${adServerHost}" >> /etc/hosts -} - -function parseLDAPCertificate() -{ - echo "create key store" - cer_begin=0 - cer_size=${#wlsADSSLCer} - cer_line_len=64 - mkdir ${SCRIPT_PWD}/security - touch ${SCRIPT_PWD}/security/AzureADLDAPCerBase64String.txt - while [ ${cer_begin} -lt ${cer_size} ] - do - cer_sub=${wlsADSSLCer:$cer_begin:$cer_line_len} - echo ${cer_sub} >> ${SCRIPT_PWD}/security/AzureADLDAPCerBase64String.txt - cer_begin=$((cer_begin+64)) - done - - openssl base64 -d -in ${SCRIPT_PWD}/security/AzureADLDAPCerBase64String.txt -out ${SCRIPT_PWD}/security/AzureADTrust.cer - addsCertificate=${SCRIPT_PWD}/security/AzureADTrust.cer -} - -function importAADCertificate() -{ - # import the key to java security - . $oracleHome/oracle_common/common/bin/setWlstEnv.sh - # For AAD failure: exception happens when importing certificate to JDK 11.0.7 - # ISSUE: https://github.com/wls-eng/arm-oraclelinux-wls/issues/109 - # JRE was removed since JDK 11. - java_version=$(java -version 2>&1 | sed -n ';s/.* version "\(.*\)\.\(.*\)\..*"/\1\2/p;') - if [ ${java_version:0:3} -ge 110 ]; - then - java_cacerts_path=${JAVA_HOME}/lib/security/cacerts - else - java_cacerts_path=${JAVA_HOME}/jre/lib/security/cacerts - fi - - # remove existing certificate. - queryAADTrust=$(${JAVA_HOME}/bin/keytool -list -keystore ${java_cacerts_path} -storepass changeit | grep "aadtrust") - if [ -n "$queryAADTrust" ]; - then - sudo ${JAVA_HOME}/bin/keytool -delete -alias aadtrust -keystore ${java_cacerts_path} -storepass changeit - fi - - sudo ${JAVA_HOME}/bin/keytool -noprompt -import -alias aadtrust -file ${addsCertificate} -keystore ${java_cacerts_path} -storepass changeit - -} - -function importAADCertificateIntoWLSCustomTrustKeyStore() -{ - if [ "${isCustomSSLEnabled,,}" == "true" ]; - then - # set java home - . $oracleHome/oracle_common/common/bin/setWlstEnv.sh - - #validate Trust keystore - sudo ${JAVA_HOME}/bin/keytool -list -v -keystore ${DOMAIN_PATH}/${wlsDomainName}/keystores/trust.keystore -storepass ${customTrustKeyStorePassPhrase} -storetype ${customTrustKeyStoreType} | grep 'Entry type:' | grep 'trustedCertEntry' - - if [[ $? != 0 ]]; then - echo "Error : Trust Keystore Validation Failed !!" - exit 1 - fi - - # For SSL enabled causes AAD failure #225 - # ISSUE: https://github.com/wls-eng/arm-oraclelinux-wls/issues/225 - - echo "Importing AAD Certificate into WLS Custom Trust Key Store: " - - sudo ${JAVA_HOME}/bin/keytool -noprompt -import -trustcacerts -keystore ${DOMAIN_PATH}/${wlsDomainName}/keystores/trust.keystore -storepass ${customTrustKeyStorePassPhrase} -alias aadtrust -file ${addsCertificate} -storetype ${customTrustKeyStoreType} - else - echo "customSSL not enabled. Not required to configure AAD for WebLogic Custom SSL" - fi -} - -function configureSSL() -{ - echo "configure ladp ssl" - sudo chown -R ${USER_ORACLE}:${GROUP_ORACLE} ${SCRIPT_PATH} - runuser -l ${USER_ORACLE} -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST ${SCRIPT_PATH}/configure-ssl.py" - - errorCode=$? - if [ $errorCode -eq 1 ] - then - echo "Exception occurs during SSL configuration, please check." - exit 1 - fi -} - -function configureAzureActiveDirectory() -{ - echo "create Azure Active Directory provider" - sudo chown -R ${USER_ORACLE}:${GROUP_ORACLE} ${SCRIPT_PATH} - runuser -l ${USER_ORACLE} -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST ${SCRIPT_PATH}/configure-active-directory.py" - - errorCode=$? - if [ $errorCode -eq 1 ] - then - echo "Exception occurs during Azure Active Directory configuration, please check." - exit 1 - fi -} - -function restartAdminServerService() -{ - echo "Restart weblogic admin server service" - sudo systemctl stop wls_admin - sudo systemctl start wls_admin -} - -#This function to check admin server status -function wait_for_admin() -{ - #check admin server status - count=1 - CHECK_URL="http://$wlsAdminURL/weblogic/ready" - status=`curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}` - echo "Check admin server status" - while [[ "$status" != "200" ]] - do - echo "." - count=$((count+1)) - if [ $count -le 30 ]; - then - sleep 1m - else - echo "Error : Maximum attempts exceeded while checking admin server status" - exit 1 - fi - status=`curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}` - if [ "$status" == "200" ]; - then - echo "WebLogic Server is running..." - break - fi - done -} - -function cleanup() -{ - echo "Cleaning up temporary files..." - rm -f -r ${SCRIPT_PATH} - rm -rf ${SCRIPT_PWD}/security/* - echo "Cleanup completed." -} - -function enableTLSv12onJDK8() -{ - if ! grep -q "${STRING_ENABLE_TLSV12}" ${wlsDomainPath}/bin/setDomainEnv.sh; then - cat <>${wlsDomainPath}/bin/setDomainEnv.sh -# Append -Djdk.tls.client.protocols to JAVA_OPTIONS in jdk8 -# Enable TLSv1.2 -\${JAVA_HOME}/bin/java -version 2>&1 | grep -e "1[.]8[.][0-9]*_" > /dev/null -javaStatus=$? - -if [[ "\${javaStatus}" = "0" && "\${JAVA_OPTIONS}" != *"${JAVA_OPTIONS_TLS_V12}"* ]]; then - JAVA_OPTIONS="\${JAVA_OPTIONS} ${JAVA_OPTIONS_TLS_V12}" - export JAVA_OPTIONS -fi -EOF -fi -} - -function restartCluster() -{ - cat <${SCRIPT_PWD}/restart-cluster.py -# Connect to the AdminServer. -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') -print "Restart cluster." -try: - print "Shutdown cluster." - shutdown('$WLS_CLUSTER_NAME', 'Cluster') - print "Start cluster." - start('$WLS_CLUSTER_NAME', 'Cluster') -except: - dumpStack() - -disconnect() -EOF - - . $oracleHome/oracle_common/common/bin/setWlstEnv.sh - java $WLST_ARGS weblogic.WLST ${SCRIPT_PWD}/restart-cluster.py - errorCode=$? - if [ $errorCode -eq 1 ] - then - echo "Failed to restart cluster." - exit 1 - fi -} - -function createTempFolder() -{ - SCRIPT_PATH="/u01/tmp" - sudo rm -f -r ${SCRIPT_PATH} - sudo mkdir ${SCRIPT_PATH} - sudo rm -rf $SCRIPT_PATH/* -} - -LDAP_USER_NAME='sAMAccountName' -LDAP_USER_FROM_NAME_FILTER='(&(sAMAccountName=%u)(objectclass=user))' -JAVA_OPTIONS_TLS_V12="-Djdk.tls.client.protocols=TLSv1.2" -STRING_ENABLE_TLSV12="Append -Djdk.tls.client.protocols to JAVA_OPTIONS in jdk8" -WLS_CLUSTER_NAME="cluster1" -WLS_DYNAMIC_SERVER_TEMPLATE="myServerTemplate" -SCRIPT_PWD=`pwd` -USER_ORACLE="oracle" -GROUP_ORACLE="oracle" -DOMAIN_PATH="/u01/domains" - -read wlsUserName wlsPassword wlsDomainName adProviderName adServerHost adServerPort adPrincipal adPassword adGroupBaseDN adUserBaseDN oracleHome wlsAdminHost wlsAdminPort wlsADSSLCer wlsLDAPPublicIP wlsAdminServerName wlsDomainPath isCustomSSLEnabled customTrustKeyStorePassPhrase customTrustKeyStoreType vmIndex - -isCustomSSLEnabled="${isCustomSSLEnabled,,}" - -if [ "${isCustomSSLEnabled,,}" == "true" ]; -then - customTrustKeyStorePassPhrase=$(echo "$customTrustKeyStorePassPhrase" | base64 --decode) - customTrustKeyStoreType=$(echo "$customTrustKeyStoreType" | base64 --decode) -fi - -wlsAdminURL=$wlsAdminHost:$wlsAdminPort - -if [ $vmIndex -eq 0 ]; -then - createTempFolder - echo "check status of admin server" - wait_for_admin - - echo "start to configure Azure Active Directory" - enableTLSv12onJDK8 - createAADProvider_model - createSSL_model - mapLDAPHostWithPublicIP - parseLDAPCertificate - importAADCertificate - importAADCertificateIntoWLSCustomTrustKeyStore - configureSSL - configureAzureActiveDirectory - restartAdminServerService - - echo "Waiting for admin server to be available" - wait_for_admin - echo "Weblogic admin server is up and running" - restartCluster - cleanup -else - createTempFolder - mapLDAPHostWithPublicIP - parseLDAPCertificate - importAADCertificate - importAADCertificateIntoWLSCustomTrustKeyStore - cleanup -fi - diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/datasourceConfig-mysql.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/datasourceConfig-mysql.sh new file mode 100644 index 000000000..54fae1aaf --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/datasourceConfig-mysql.sh @@ -0,0 +1,186 @@ +#!/bin/bash +# Copyright (c) 2021, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +# +#read arguments from stdin +read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsShibboleth jdbcDataSourceName dsConnectionURL dsUser dsPassword dbGlobalTranPro enablePswlessConnection wlsClusterName + +if [ -z "$wlsClusterName" ]; then + wlsClusterName="cluster1" +fi + +wlsAdminURL=$wlsAdminHost:$wlsAdminPort +hostName=`hostname` + +#Function to output message to StdErr +function echo_stderr () +{ + echo "$@" >&2 +} + +#Function to display usage message +function usage() +{ + echo_stderr "./configDatasource.sh <<< \"\"" +} + +function validateInput() +{ + # parse base64 string + wlsShibboleth=$(echo "${wlsShibboleth}" | base64 -d) + jdbcDataSourceName=$(echo "${jdbcDataSourceName}" | base64 -d) + dsConnectionURL=$(echo "${dsConnectionURL}" | base64 -d) + dsPassword=$(echo "${dsPassword}" | base64 -d) + + if [ -z "$oracleHome" ]; + then + echo _stderr "Please provide oracleHome" + exit 1 + fi + + if [ -z "$wlsAdminHost" ]; + then + echo _stderr "Please provide WeblogicServer hostname" + exit 1 + fi + + if [ -z "$wlsAdminPort" ]; + then + echo _stderr "Please provide Weblogic admin port" + exit 1 + fi + + if [ -z "$wlsUserName" ]; + then + echo _stderr "Please provide Weblogic username" + exit 1 + fi + + if [ -z "$wlsShibboleth" ]; + then + echo _stderr "Please provide Weblogic password" + exit 1 + fi + + if [ -z "$jdbcDataSourceName" ]; + then + echo _stderr "Please provide JDBC datasource name to be configured" + exit 1 + fi + + if [ -z "$dsConnectionURL" ]; + then + echo _stderr "Please provide Azure database of MySQL URL in the format 'jdbc:oracle:thin:@:/'" + exit 1 + fi + + if [ -z "$dsUser" ]; + then + echo _stderr "Please provide Azure database of MySQL user name" + exit 1 + fi + + if [ -z "$dsPassword" ]; + then + echo _stderr "Please provide Azure database of MySQL password" + exit 1 + fi + + if [ -z "$dbGlobalTranPro" ]; + then + echo _stderr "Please provide Global transactions protocol" + exit 1 + fi + + if [ -z "${enablePswlessConnection}" ]; + then + echo _stderr "Please provide enablePswlessConnection to identity if enabling passwordless connection." + exit 1 + fi + + if [ -z "$wlsClusterName" ]; + then + echo _stderr "Please provide Weblogic target cluster name" + exit 1 + fi + + # reset password + if [[ "${enablePswlessConnection,,}" == "true" ]]; then + dsPassword="" + fi +} + +function createJDBCSource_model() +{ + local driverName="com.mysql.jdbc.Driver" + if [[ "${enablePswlessConnection,,}" == "true" ]]; then + driverName="com.mysql.cj.jdbc.Driver" + fi + + echo "Creating JDBC data source with name $jdbcDataSourceName" + cat <${scriptPath}/create_datasource.py +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') +edit("$hostName") +startEdit() +cd('/') +try: + cmo.createJDBCSystemResource('$jdbcDataSourceName') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName') + cmo.setName('$jdbcDataSourceName') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDataSourceParams/$jdbcDataSourceName') + set('JNDINames',jarray.array([String('$jdbcDataSourceName')], String)) + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName') + cmo.setDatasourceType('GENERIC') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDriverParams/$jdbcDataSourceName') + cmo.setUrl('$dsConnectionURL') + cmo.setDriverName('$driverName') + cmo.setPassword('$dsPassword') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCConnectionPoolParams/$jdbcDataSourceName') + cmo.setTestTableName('SQL ISVALID\r\n\r\n\r\n\r\n') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDriverParams/$jdbcDataSourceName/Properties/$jdbcDataSourceName') + cmo.createProperty('user') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDriverParams/$jdbcDataSourceName/Properties/$jdbcDataSourceName/Properties/user') + cmo.setValue('$dsUser') + cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDataSourceParams/$jdbcDataSourceName') + cmo.setGlobalTransactionsProtocol('${dbGlobalTranPro}') + cd('/JDBCSystemResources/$jdbcDataSourceName') + set('Targets',jarray.array([ObjectName('com.bea:Name=$wlsClusterName,Type=Cluster')], ObjectName)) + save() + resolve() + activate() +except Exception, e: + e.printStackTrace() + dumpStack() + undo('true',defaultAnswer='y') + cancelEdit('y') + destroyEditSession("$hostName",force = true) + raise("$jdbcDataSourceName configuration failed") +destroyEditSession("$hostName",force = true) +disconnect() +EOF +} + +function createTempFolder() +{ + scriptPath="/u01/tmp" + sudo rm -f -r ${scriptPath} + sudo mkdir ${scriptPath} + sudo rm -rf $scriptPath/* +} + +createTempFolder +validateInput +createJDBCSource_model + +sudo chown -R oracle:oracle ${scriptPath} +runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST ${scriptPath}/create_datasource.py" + +errorCode=$? +if [ $errorCode -eq 1 ] +then + echo "Exception occurs during DB configuration, please check." + exit 1 +fi + +echo "Cleaning up temporary files..." +rm -f -r ${scriptPath} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/datasourceConfig-oracle.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/datasourceConfig-oracle.sh index 89057881a..5a6983b26 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/datasourceConfig-oracle.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/datasourceConfig-oracle.sh @@ -2,7 +2,7 @@ # Copyright (c) 2021, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. # -read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsPassword jdbcDataSourceName dsConnectionURL dsUser dsPassword wlsClusterName +read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsShibboleth jdbcDataSourceName dsConnectionURL dsUser dsPassword dbGlobalTranPro enablePswlessConnection wlsClusterName if [ -z ${wlsClusterName} ]; then wlsClusterName='cluster1' @@ -25,6 +25,11 @@ function usage() function validateInput() { + # parse base64 string + wlsShibboleth=$(echo "${wlsShibboleth}" | base64 -d) + jdbcDataSourceName=$(echo "${jdbcDataSourceName}" | base64 -d) + dsConnectionURL=$(echo "${dsConnectionURL}" | base64 -d) + dsPassword=$(echo "${dsPassword}" | base64 -d) if [ -z "$oracleHome" ]; then @@ -50,7 +55,7 @@ function validateInput() exit 1 fi - if [ -z "$wlsPassword" ]; + if [ -z "$wlsShibboleth" ]; then echo _stderr "Please provide Weblogic password" exit 1 @@ -80,19 +85,35 @@ function validateInput() exit 1 fi + if [ -z "$dbGlobalTranPro" ]; + then + echo _stderr "Please provide Global transactions protocol" + exit 1 + fi + if [ -z "$wlsClusterName" ]; then echo _stderr "Please provide Weblogic target cluster name" exit 1 fi + if [ -z "${enablePswlessConnection}" ]; + then + echo _stderr "Please provide enablePswlessConnection to identity if enabling passwordless connection." + exit 1 + fi + + # reset password + if [[ "${enablePswlessConnection,,}" == "true" ]]; then + dsPassword="" + fi } function createJDBCSource_model() { echo "Creating JDBC data source with name $jdbcDataSourceName" cat <${scriptPath}/create_datasource.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') edit("$hostName") startEdit() cd('/') @@ -115,7 +136,7 @@ try: cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDriverParams/$jdbcDataSourceName/Properties/$jdbcDataSourceName/Properties/user') cmo.setValue('$dsUser') cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDataSourceParams/$jdbcDataSourceName') - cmo.setGlobalTransactionsProtocol('EmulateTwoPhaseCommit') + cmo.setGlobalTransactionsProtocol('${dbGlobalTranPro}') cd('/JDBCSystemResources/$jdbcDataSourceName') set('Targets',jarray.array([ObjectName('com.bea:Name=$wlsClusterName,Type=Cluster')], ObjectName)) save() diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/datasourceConfig-postgresql.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/datasourceConfig-postgresql.sh index c0127c336..cf840f119 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/datasourceConfig-postgresql.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/datasourceConfig-postgresql.sh @@ -2,7 +2,7 @@ # Copyright (c) 2021, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. # -read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsPassword jdbcDataSourceName dsConnectionURL dsUser dsPassword wlsClusterName +read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsShibboleth jdbcDataSourceName dsConnectionURL dsUser dsPassword dbGlobalTranPro enablePswlessConnection wlsClusterName if [ -z ${wlsClusterName} ]; then wlsClusterName='cluster1' @@ -25,6 +25,11 @@ function usage() function validateInput() { + # parse base64 string + wlsShibboleth=$(echo "${wlsShibboleth}" | base64 -d) + jdbcDataSourceName=$(echo "${jdbcDataSourceName}" | base64 -d) + dsConnectionURL=$(echo "${dsConnectionURL}" | base64 -d) + dsPassword=$(echo "${dsPassword}" | base64 -d) if [ -z "$oracleHome" ]; then @@ -50,7 +55,7 @@ function validateInput() exit 1 fi - if [ -z "$wlsPassword" ]; + if [ -z "$wlsShibboleth" ]; then echo _stderr "Please provide Weblogic password" exit 1 @@ -80,19 +85,35 @@ function validateInput() exit 1 fi + if [ -z "$dbGlobalTranPro" ]; + then + echo _stderr "Please provide Global transactions protocol" + exit 1 + fi + if [ -z "$wlsClusterName" ]; then echo _stderr "Please provide Weblogic target cluster name" exit 1 fi + if [ -z "${enablePswlessConnection}" ]; + then + echo _stderr "Please provide enablePswlessConnection to identity if enabling passwordless connection." + exit 1 + fi + + # reset password + if [[ "${enablePswlessConnection,,}" == "true" ]]; then + dsPassword="" + fi } function createJDBCSource_model() { echo "Creating JDBC data source with name $jdbcDataSourceName" cat <${scriptPath}/create_datasource.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') edit("$hostName") startEdit() cd('/') @@ -115,7 +136,7 @@ try: cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDriverParams/$jdbcDataSourceName/Properties/$jdbcDataSourceName/Properties/user') cmo.setValue('$dsUser') cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDataSourceParams/$jdbcDataSourceName') - cmo.setGlobalTransactionsProtocol('EmulateTwoPhaseCommit') + cmo.setGlobalTransactionsProtocol('${dbGlobalTranPro}') cd('/JDBCSystemResources/$jdbcDataSourceName') set('Targets',jarray.array([ObjectName('com.bea:Name=$wlsClusterName,Type=Cluster')], ObjectName)) save() diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/datasourceConfig-sqlserver.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/datasourceConfig-sqlserver.sh index 5ea15d856..696a21c5f 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/datasourceConfig-sqlserver.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/datasourceConfig-sqlserver.sh @@ -2,7 +2,7 @@ # Copyright (c) 2021, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. # -read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsPassword jdbcDataSourceName dsConnectionURL dsUser dsPassword wlsClusterName +read oracleHome wlsAdminHost wlsAdminPort wlsUserName wlsShibboleth jdbcDataSourceName dsConnectionURL dsUser dsPassword dbGlobalTranPro enablePswlessConnection wlsClusterName if [ -z ${wlsClusterName} ]; then wlsClusterName='cluster1' @@ -25,6 +25,11 @@ function usage() function validateInput() { + # parse base64 string + wlsShibboleth=$(echo "${wlsShibboleth}" | base64 -d) + jdbcDataSourceName=$(echo "${jdbcDataSourceName}" | base64 -d) + dsConnectionURL=$(echo "${dsConnectionURL}" | base64 -d) + dsPassword=$(echo "${dsPassword}" | base64 -d) if [ -z "$oracleHome" ]; then @@ -50,7 +55,7 @@ function validateInput() exit 1 fi - if [ -z "$wlsPassword" ]; + if [ -z "$wlsShibboleth" ]; then echo _stderr "Please provide Weblogic password" exit 1 @@ -80,19 +85,36 @@ function validateInput() exit 1 fi + if [ -z "$dbGlobalTranPro" ]; + then + echo _stderr "Please provide Global transactions protocol" + exit 1 + fi + if [ -z "$wlsClusterName" ]; then echo _stderr "Please provide Weblogic target cluster name" exit 1 fi + if [ -z "${enablePswlessConnection}" ]; + then + echo _stderr "Please provide enablePswlessConnection to identity if enabling passwordless connection." + exit 1 + fi + + # reset password and user + if [[ "${enablePswlessConnection,,}" == "true" ]]; then + dsPassword="" + dsUser="" + fi } function createJDBCSource_model() { echo "Creating JDBC data source with name $jdbcDataSourceName" cat <${scriptPath}/create_datasource.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') edit("$hostName") startEdit() cd('/') @@ -115,7 +137,7 @@ try: cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDriverParams/$jdbcDataSourceName/Properties/$jdbcDataSourceName/Properties/user') cmo.setValue('$dsUser') cd('/JDBCSystemResources/$jdbcDataSourceName/JDBCResource/$jdbcDataSourceName/JDBCDataSourceParams/$jdbcDataSourceName') - cmo.setGlobalTransactionsProtocol('EmulateTwoPhaseCommit') + cmo.setGlobalTransactionsProtocol('${dbGlobalTranPro}') cd('/JDBCSystemResources/$jdbcDataSourceName') set('Targets',jarray.array([ObjectName('com.bea:Name=$wlsClusterName,Type=Cluster')], ObjectName)) save() diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/elkIntegrationForConfiguredCluster.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/elkIntegrationForConfiguredCluster.sh deleted file mode 100644 index 8581b026d..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/elkIntegrationForConfiguredCluster.sh +++ /dev/null @@ -1,759 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# -#Function to output message to StdErr -function echo_stderr() { - echo "$@" >&2 -} - -#Function to display usage message -function usage() { - echo_stderr "./elkIntegrationForConfiguredCluster.sh <<< \"\"" -} - -function validate_input() { - if [ -z "$oracleHome" ]; then - echo_stderr "oracleHome is required. " - exit 1 - fi - - if [ -z "$wlsAdminURL" ]; then - echo_stderr "wlsAdminURL is required. " - exit 1 - fi - - if [[ -z "$wlsUserName" || -z "$wlsPassword" ]]; then - echo_stderr "wlsUserName or wlsPassword is required. " - exit 1 - fi - - if [ -z "$wlsAdminServerName" ]; then - echo_stderr "wlsAdminServerName is required. " - exit 1 - fi - - if [ -z "$elasticURI" ]; then - echo_stderr "elasticURI is required. " - exit 1 - fi - - if [[ -z "$elasticUserName" || -z "$elasticPassword" ]]; then - echo_stderr "elasticUserName or elasticPassword is required. " - exit 1 - fi - - if [ -z "$wlsDomainName" ]; then - echo_stderr "wlsDomainName is required. " - exit 1 - fi - - if [ -z "$wlsDomainPath" ]; then - echo_stderr "wlsDomainPath is required. " - exit 1 - fi - - if [ -z "$index" ]; then - echo_stderr "index is required. " - exit 1 - fi - - if [ -z "$logsToIntegrate" ]; then - echo_stderr "logsToIntegrate is required. " - exit 1 - fi - - if [ -z "$logIndex" ]; then - echo_stderr "logIndex is required. " - exit 1 - fi - - if [ -z "$managedServerPrefix" ]; then - echo_stderr "managedServerPrefix is required. " - exit 1 - fi -} - -# Set access log with format: date time time-taken bytes c-ip s-ip c-dns s-dns cs-method cs-uri sc-status sc-comment ctx-ecid -# Redirect stdout logging enabled: true -# Redirect stderr logging enabled: true -# Stack Traces to stdout: true -function create_wls_log_model() { - cat <${SCRIPT_PATH}/configure-wls-log.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') -servers=cmo.getServers() - -try: - edit("$hostName") - startEdit() - for server in servers: - bean="/ServerLifeCycleRuntimes/"+server.getName() - cd('/Servers/'+server.getName()+'/WebServer/'+server.getName()+'/WebServerLog/'+server.getName()) - cmo.setLogFileFormat('extended') - cmo.setELFFields('date time time-taken bytes c-ip s-ip c-dns s-dns cs-method cs-uri sc-status sc-comment ctx-ecid ctx-rid') - - cd('/Servers/'+server.getName()+'/Log/'+server.getName()) - cmo.setRedirectStderrToServerLogEnabled(true) - cmo.setRedirectStdoutToServerLogEnabled(true) - cmo.setStdoutLogStack(true) - - save() - resolve() - activate() -except: - stopEdit('y') - sys.exit(1) - -destroyEditSession("$hostName",force = true) -disconnect() -EOF -} - -# Remove existing Logstash -function remove_logstash() { - sudo systemctl status logstash - if [ $? -ne 0 ]; then - sudo systemctl stop logstash - fi - - sudo yum remove -y -v logstash - if [ $? -ne 0 ]; then - echo_stderr "Fail to remove existing Logstash." - exit 1 - fi -} - -# Install Logstash -function install_logstash() { - sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch - - cat </etc/yum.repos.d/logstash.repo -[logstash-7.x] -name=Elastic repository for 7.x packages -baseurl=https://artifacts.elastic.co/packages/7.x/yum -gpgcheck=1 -gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch -enabled=1 -autorefresh=1 -type=rpm-md -EOF - sudo yum install -y -v logstash - if [ ! -d "/usr/share/logstash" ]; then - echo_stderr "Fail to install Logstash." - exit 1 - fi -} - -# Start Logstash service -function start_logstash() { - sudo systemctl enable logstash - sudo systemctl daemon-reload - - #Start logstash - attempt=1 - while [[ $attempt -lt 4 ]]; do - echo "Starting logstash service attempt $attempt" - sudo systemctl start logstash - attempt=$(expr $attempt + 1) - sudo systemctl status logstash | grep running - if [[ $? == 0 ]]; then - echo "logstash service started successfully" - break - fi - sleep 1m - done -} - -# Configure Logstash: -# * grok patterns -> /etc/logstash/patterns/weblogic-logstash-patterns.txt -# * conf files -> /etc/logstash/conf.d -# * JAVA_HOME -> /etc/logstash/startup.options -# * create logstash start up -# Examples for patterns: -# * ACCESSDATE -# * parse date of access -# * 2020-09-01 -# * DBDATETIME -# * parse data source datetime -# * Tue Sep 01 05:05:41 UTC 2020 -# * DSIDORTIMESTAMP -# * parse data source dynamic fields: id | timestamp, one of them exists. -# * timestamp: Tue Sep 01 05:05:41 UTC 2020 -# * id: 64 -# * DSPARTITION -# * parse partition info. -# * [partition-name: DOMAIN] [partition-id: 0] -# * [partition-id: 0] [partition-name: DOMAIN] -# * DSWEBLOGICMESSAGE -# * parse data source user id or error messsage. -# * error: Java stack trace -# * user id: -# * WEBLOGICDIAGMESSAGE -# * parse domain log message. -# * e.g. Java stack trace -# * e.g. Self-tuning thread pool contains 0 running threads, 2 idle threads, and 13 standby threads -# * WEBLOGICDOMAINDATE -# * parse domain|server log datetime. -# * from wls 14: Sep 1, 2020, 5:41:51,040 AM Coordinated Universal Time -# * from wls 12: Sep 1, 2020 5:41:51,040 AM Coordinated Universal Time -# * WEBLOGICLOGPARTITION -# * parse partition info in domain log. -# * [severity-value: 64] -# * [severity-value: 64] [rid: 0] -# * [severity-value: 64] [partition-id: 0] [partition-name: DOMAIN ] -# * [severity-value: 64] [rid: 0] [partition-id: 0] [partition-name: DOMAIN ] -# * WEBLOGICSERVERLOGPARTITION -# * parse partition info in server log. -# * [severity-value: 64] -# * [severity-value: 64] [rid: 0] -# * [severity-value: 64] [partition-id: 0] [partition-name: DOMAIN ] -# * [severity-value: 64] [rid: 0] [partition-id: 0] [partition-name: DOMAIN ] -# * WEBLOGICSERVERRID -# * parse dynamic filed rid in server log. -# * [rid: 0] -# * WEBLOGICSERVERMESSAGE -# * parse field message in server log. -# * e.g. Java stack trace -# * e.g. Self-tuning thread pool contains 0 running threads, 2 idle threads, and 13 standby threads -# * WEBLOGICSTDDATE -# * parse field date in std log. -# * Aug 31, 2020 5:37:27,646 AM UTC -# * Aug 31, 2020 5:37:27 AM UTC -function configure_lostash() { - echo "create patterns" - rm -f -r /etc/logstash/patterns - if [ -d "/etc/logstash/patterns" ]; then - rm -f /etc/logstash/patterns/weblogic-logstash-patterns.txt - else - mkdir /etc/logstash/patterns - fi - cat </etc/logstash/patterns/weblogic-logstash-patterns.txt -ACCESSDATE ^\d{4}[./-]%{MONTHNUM}[./-]%{MONTHDAY} -DBDATETIME %{DAY} %{MONTH:db_month} %{MONTHDAY:db_day} %{HOUR:db_hour}:%{MINUTE:db_minute}:%{SECOND:db_second} %{TZ:db_tz} %{YEAR:db_year} -DSIDORTIMESTAMP (?(\b(?:[1-9][0-9]*)\b))|%{DBDATETIME:ds_timestamp} -DSPARTITION (?:\[partition-id: %{INT:ds_partitionId}\] \[partition-name: %{DATA:ds_partitionName}\]\s)|(?:\[partition-name: %{DATA:ds_partitionName}\] \[partition-id: %{INT:ds_partitionId}\]\s) -DSWEBLOGICMESSAGE (?(.|\r|\n)*)|%{GREEDYDATA:ds_user} -JAVAPACKAGE ([a-zA-Z_$][a-zA-Z\d_$]*\.)*[a-zA-Z_$][a-zA-Z\d_$]* -NODEMANAGERMESSAGE (?(.|\r|\n[^A-Za-z0-9])*)|%{GREEDYDATA:node_message} -NODEMANAGEREND (<%{WORDNOSPACES:node_domain}>\s<%{WORDNOSPACES:node_server}>\s<%{NODEMANAGERMESSAGE}>)|(<%{GREEDYDATA:node_messageType}>\s<%{NODEMANAGERMESSAGE}>)|<%{NODEMANAGERMESSAGE}> -WEBLOGICDIAGMESSAGE (?(.|\r|\n)*)|%{GREEDYDATA:diag_message} -WEBLOGICDOMAINDATE %{MONTH:tmp_month} %{MONTHDAY:tmp_day}, %{YEAR:tmp_year},? %{HOUR:tmp_hour}:%{MINUTE:tmp_min}:%{SECOND:tmp_second},(?([0-9]{3})) (?(AM|PM)) -WEBLOGICLOGPARTITION (?:\s\[rid: %{DATA:diag_rid}\] \[partition-id: %{INT:diag_partitionId}\] \[partition-name: %{DATA:diag_partitionName}\]\s)|(?:\s\[partition-id: %{INT:diag_partitionId}\] \[partition-name: %{DATA:diag_partitionName}\]\s)|(?:\s\[rid: %{DATA:diag_rid}\]\s)|(\s) -WEBLOGICSERVERLOGPARTITION (?:\s\[rid: %{DATA:log_rid}\] \[partition-id: %{INT:log_partitionId}\] \[partition-name: %{DATA:log_partitionName}\]\s)|(?:\s\[partition-id: %{INT:log_partitionId}\] \[partition-name: %{DATA:log_partitionName}\]\s)|(?:\s\[rid: %{DATA:log_rid}\]\s)|(\s) -WEBLOGICSERVERRID (?:\s\[rid: %{WORDNOSPACES:log_rid}\]\s)|(\s) -WEBLOGICSERVERMESSAGE (?(.|\r|\n)*)|%{GREEDYDATA:log_message} -WEBLOGICSTDDATE %{MONTH:tmp_month} %{MONTHDAY:tmp_day}, %{YEAR:tmp_year},? %{HOUR:tmp_hour}:%{MINUTE:tmp_min}:%{SECOND:tmp_second} (?(AM|PM)) -WEBLOGICSTDMESSAGE (?(.|\r|\n[^A-Za-z0-9])*)|%{GREEDYDATA:out_message} -WEBLOGICSTDDYNAMICID (<%{WORDNOSPACES:out_messageId}>\s<%{WEBLOGICSTDMESSAGE}>)|<%{WEBLOGICSTDMESSAGE}> -WORDNOSPACES [^ ]* -WORDNOBRACKET [^\]]* -WORDWITHSPACE (\b\w+\b|\s)* -EOF - - if [ $index -eq 0 ]; then - serverName=$wlsAdminServerName - else - serverName="${managedServerPrefix}${index}" - fi - wlsLogPath="${wlsDomainPath}/servers/${serverName}/logs" - privateIP=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/') - - rm -f /etc/logstash/conf.d/weblogic-logs.conf - cat </etc/logstash/conf.d/weblogic-logs.conf -input { -EOF - - if [[ -n $(echo ${logsToIntegrate} | grep "HTTPAccessLog") ]]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { - path => "${wlsLogPath}/access.log" - start_position => beginning - } -EOF - fi - - if [[ -n $(echo ${logsToIntegrate} | grep "ServerLog") ]]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { - path => "${wlsLogPath}/${serverName}.log" - codec => multiline { - pattern => "^####" - negate => true - what => "previous" - } - start_position => beginning - } -EOF - fi - - if [[ -n $(echo ${logsToIntegrate} | grep "DomainLog") ]]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { - path => "${wlsLogPath}/${wlsDomainName}.log" - codec => multiline { - pattern => "^####" - negate => true - what => "previous" - } - start_position => beginning - } -EOF - fi - - if [[ -n $(echo ${logsToIntegrate} | grep "DataSourceLog") ]]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { - path => "${wlsLogPath}/datasource.log" - codec => multiline { - pattern => "^####" - negate => true - what => "previous" - } - start_position => beginning - } -EOF - fi - - if [[ -n $(echo ${logsToIntegrate} | grep "StandardErrorAndOutput") ]]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { - path => "${wlsLogPath}/${serverName}.out" - codec => multiline { - pattern => "^<" - negate => true - what => "previous" - } - start_position => beginning - } -EOF - fi - - if [[ -n $(echo ${logsToIntegrate} | grep "NodeManagerLog") ]]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { - path => "${wlsDomainPath}/nodemanager/nodemanager.log" - codec => multiline { - pattern => "^<" - negate => true - what => "previous" - } - start_position => beginning - } -EOF - fi - - cat <>/etc/logstash/conf.d/weblogic-logs.conf -} -filter { - grok { - match => {"path" => "%{GREEDYDATA}/%{GREEDYDATA:type}"} - } - mutate { - add_field => { "internal_ip" => "${privateIP}" } - } - - if [type] == "${serverName}.log" { - mutate { replace => { type => "weblogic_server_log" } } - # match rid - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "####<%{WEBLOGICDOMAINDATE}%{SPACE}%{GREEDYDATA:log_timezone}>%{SPACE}<%{LOGLEVEL:log_severity}>%{SPACE}<%{GREEDYDATA:log_subSystem}>%{SPACE}<%{HOSTNAME:log_machine}>%{SPACE}<%{DATA:log_server}>%{SPACE}<%{DATA:log_thread}>%{SPACE}<%{DATA:log_userId}>%{SPACE}<%{DATA:log_transactionId}>%{SPACE}<%{DATA:log_contextId}>%{SPACE}<%{NUMBER:log_timestamp}>%{SPACE}<\[severity-value: %{INT:log_severityValue}\]%{WEBLOGICSERVERLOGPARTITION}>%{SPACE}<%{DATA:log_massageId}>%{SPACE}<%{WEBLOGICSERVERMESSAGE}>" ] - } - - mutate { - replace => ['log_date', '%{tmp_month} %{tmp_day}, %{tmp_year} %{tmp_hour}:%{tmp_min}:%{tmp_second},%{tmp_sss} %{tmp_aa}'] - } - - translate { - field => 'log_timezone' - destination => 'log_timezone' - fallback => '%{log_timezone}' - override => "true" - dictionary => { - "Coordinated Universal Time" => "UTC" - } - } - - date { - match => [ "log_date", "MMM dd, YYYY KK:mm:ss,SSS aa", "MMM d, YYYY KK:mm:ss,SSS aa"] - timezone => "%{log_timezone}" - target => "log_date" - } - mutate { - remove_field => [ 'log_timezone', 'tmp_month', 'tmp_day', 'tmp_year', 'tmp_hour', 'tmp_min', 'tmp_second', 'tmp_sss', 'tmp_aa'] - } - } - else if [type] == "access.log" { - # drop message starting with # - if [message] =~ /^#/ { - drop {} - } - mutate { replace => { type => "weblogic_access_log" } } - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "%{ACCESSDATE:acc_date}\s+%{TIME:acc_time}\s+%{NUMBER:time_taken}\s+%{NUMBER:bytes:int}\s+%{IP:c_ip}\s+%{HOSTPORT:s_ip}\s+%{IPORHOST:c_dns}\s+%{IPORHOST:s_dns}\s+%{WORD:cs_method}\s+%{URIPATHPARAM:cs_uri}\s+%{NUMBER:sc_status}\s+%{QUOTEDSTRING:sc-comment}\s+%{WORDNOSPACES:ctx-ecid}\s+%{WORDNOSPACES:ctx-rid}" ] - } - mutate { - replace => ['acc_timestamp', '%{acc_date} %{acc_time}'] - } - date { - match => [ "acc_timestamp" , "yyyy-MM-dd HH:mm:ss" ] - timezone => "UTC" - target => "acc_timestamp" - } - mutate { - remove_field => [ 'acc_date', 'acc_time'] - } - } - else if [type] == "${wlsDomainName}.log" { - mutate { replace => { type => "weblogic_domain_log" } } - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "####<%{WEBLOGICDOMAINDATE}%{SPACE}%{GREEDYDATA:diag_timezone}>%{SPACE}<%{LOGLEVEL:diag_severity}>%{SPACE}<%{GREEDYDATA:diag_subSystem}>%{SPACE}<%{HOSTNAME:diag_machine}>%{SPACE}<%{HOSTNAME:diag_server}>%{SPACE}<%{DATA:diag_thread}>%{SPACE}<%{WORDNOBRACKET:diag_userId}>%{SPACE}<%{DATA:diag_transactionId}>%{SPACE}<%{WORDNOSPACES:diag_contextId}>%{SPACE}<%{NUMBER:diag_timestamp}>%{SPACE}<\[severity-value: %{INT:diag_severityValue}\]%{WEBLOGICLOGPARTITION}>%{SPACE}<%{DATA:diag_massageId}>%{SPACE}<%{WEBLOGICDIAGMESSAGE}>" ] - } - - mutate { - replace => ['diag_date', '%{tmp_month} %{tmp_day}, %{tmp_year} %{tmp_hour}:%{tmp_min}:%{tmp_second},%{tmp_sss} %{tmp_aa}'] - } - - translate { - field => 'diag_timezone' - destination => 'diag_timezone' - fallback => '%{diag_timezone}' - override => "true" - dictionary => { - "Coordinated Universal Time" => "UTC" - } - } - - date { - match => [ "diag_date", "MMM dd, YYYY KK:mm:ss,SSS aa", "MMM d, YYYY KK:mm:ss,SSS aa"] - timezone => "%{diag_timezone}" - target => "diag_date" - } - mutate { - remove_field => [ 'diag_timezone', 'tmp_month', 'tmp_day', 'tmp_year', 'tmp_hour', 'tmp_min', 'tmp_second', 'tmp_sss', 'tmp_aa'] - } - } - else if [type] == "datasource.log" { - mutate { replace => { type => "weblogic_datasource_log" } } - # with timestamp - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "####<%{WORDNOSPACES:ds_dataSource}>%{SPACE}<%{WORDNOSPACES:ds_profileType}>%{SPACE}<%{DSIDORTIMESTAMP}>%{SPACE}<%{DSWEBLOGICMESSAGE}>%{SPACE}<%{DATA:ds_info}>%{SPACE}<%{DSPARTITION}>" ] - } - - if ([db_month]) { - # DBDATETIME %{DAY} %{MONTH:db_month} %{MONTHDAY:db_day} %{HOUR:db_hour}:%{MINUTE:db_minute}:%{SECOND:db_second} %{TZ:db_tz} %{YEAR:db_year} - mutate { - replace => ["ds_timestamp", "%{db_month} %{db_day}, %{db_year} %{db_hour}:%{db_minute}:%{db_second}"] - } - - date { - match => [ "ds_timestamp", "MMM dd, YYYY HH:mm:ss", "MMM d, YYYY HH:mm:ss"] - timezone => "%{db_tz}" - target => "ds_timestamp" - } - mutate { - remove_field => [ 'db_month','db_day','db_year','db_hour','db_minute','db_second','db_tz'] - } - } - } - else if [type] == "${serverName}.out" { - mutate { replace => { type => "weblogic_std_log" } } - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "<%{WEBLOGICSTDDATE}%{SPACE}%{WORDWITHSPACE:out_timezone}>%{SPACE}<%{WORDWITHSPACE:out_level}>%{SPACE}<%{WORDWITHSPACE:out_subsystem}>%{SPACE}%{WEBLOGICSTDDYNAMICID}"] - } - - mutate { - replace => ['out_timestamp', '%{tmp_month} %{tmp_day}, %{tmp_year} %{tmp_hour}:%{tmp_min}:%{tmp_second} %{tmp_aa}'] - } - - # CEST id does not exist in JODA-TIME, changed to CET - translate { - field => 'out_timezone' - destination => 'out_timezone' - fallback => '%{out_timezone}' - override => "true" - dictionary => { - "CEST" => "CET" - "Coordinated Universal Time" => "UTC" - } - } - - date { - match => [ "out_timestamp", "MMM dd, YYYY KK:mm:ss aa", "MMM d, YYYY KK:mm:ss aa", "MMM dd, YYYY KK:mm:ss,SSS aa", "MMM d, YYYY KK:mm:ss,SSS aa"] - timezone => "%{out_timezone}" - target => "out_timestamp" - } - mutate { - remove_field => [ 'out_timezone','tmp_month', 'tmp_day', 'tmp_year', 'tmp_hour', 'tmp_min', 'tmp_second', 'tmp_aa'] - } - } - else if [type] == "nodemanager.log" { - mutate { replace => { type => "weblogic_nodemanager_log" } } - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "<%{WEBLOGICSTDDATE}%{SPACE}%{WORDWITHSPACE:node_timezone}>%{SPACE}<%{WORDWITHSPACE:node_level}>%{SPACE}%{NODEMANAGEREND}"] - } - - mutate { - replace => ['node_timestamp', '%{tmp_month} %{tmp_day}, %{tmp_year} %{tmp_hour}:%{tmp_min}:%{tmp_second} %{tmp_aa}'] - } - - # CEST id does not exist in JODA-TIME, changed to CET - translate { - field => 'node_timezone' - destination => 'node_timezone' - fallback => '%{node_timezone}' - override => "true" - dictionary => { - "CEST" => "CET" - "Coordinated Universal Time" => "UTC" - } - } - - date { - match => [ "node_timestamp", "MMM dd, YYYY KK:mm:ss aa", "MMM d, YYYY KK:mm:ss aa", "MMM dd, YYYY KK:mm:ss,SSS aa", "MMM d, YYYY KK:mm:ss,SSS aa"] - timezone => "%{node_timezone}" - target => "node_timestamp" - } - mutate { - remove_field => [ 'node_timezone','tmp_month', 'tmp_day', 'tmp_year', 'tmp_hour', 'tmp_min', 'tmp_second', 'tmp_aa'] - } - } -} -output { - elasticsearch { - hosts => "${elasticURI}" - user => "${elasticUserName}" - password => "${elasticPassword}" - index => "${logIndex}" - } -} -EOF - - # Add JAVA_HOME to startup.options - cp /etc/logstash/startup.options /etc/logstash/startup.options.elksave - sed -i -e "/JAVACMD/a\\JAVA_HOME=${JAVA_HOME}" /etc/logstash/startup.options - sed -i -e "s:LS_USER=.*:LS_USER=${userOracle}:g" /etc/logstash/startup.options - sed -i -e "s:LS_GROUP=.*:LS_GROUP=${groupOracle}:g" /etc/logstash/startup.options - - # For Java 11 - # ISSUE: https://github.com/elastic/logstash/issues/10496 - java_version=$(java -version 2>&1 | sed -n ';s/.* version "\(.*\)\.\(.*\)\..*"/\1\2/p;') - if [ ${java_version:0:3} -ge 110 ]; then - cp /etc/logstash/jvm.options /etc/logstash/jvm.options.elksave - cat <>/etc/logstash/jvm.options ---add-opens java.base/sun.nio.ch=org.jruby.dist ---add-opens java.base/java.io=org.jruby.dist -EOF - fi - - # create start up for logstash - /usr/share/logstash/bin/system-install /etc/logstash/startup.options - if [ $? -ne 0 ]; then - echo_stderr "Failed to set up logstash service." - exit 1 - fi - - sudo chown -R ${userOracle}:${groupOracle} /var/lib/logstash - sudo chown -R ${userOracle}:${groupOracle} /etc/logstash -} - -function configure_wls_log() { - echo "Configure WebLogic Log" - sudo chown -R ${userOracle}:${groupOracle} ${SCRIPT_PATH} - runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST ${SCRIPT_PATH}/configure-wls-log.py" - - errorCode=$? - if [ $errorCode -eq 1 ]; then - echo "Exception occurs during ELK configuration, please check." - exit 1 - fi -} - -function setup_javahome() { - . $oracleHome/oracle_common/common/bin/setWlstEnv.sh -} - -function restart_admin_service() { - echo "Restart weblogic admin server" - echo "Stop admin server" - shutdown_admin - sudo systemctl start wls_admin - echo "Waiting for admin server to be available" - wait_for_admin - echo "Weblogic admin server is up and running" -} - -function restartManagedServers() { - echo "Restart managed servers" - cat <${SCRIPT_PATH}/restart-managedServer.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') -servers=cmo.getServers() -domainRuntime() -print "Restart the servers which are in RUNNING status" -for server in servers: - bean="/ServerLifeCycleRuntimes/"+server.getName() - serverbean=getMBean(bean) - if (serverbean.getState() in ("RUNNING")) and (server.getName() != '${wlsAdminServerName}'): - try: - print "Stop the Server ",server.getName() - shutdown(server.getName(),server.getType(),ignoreSessions='true',force='true') - print "Start the Server ",server.getName() - start(server.getName(),server.getType()) - except: - print "Failed restarting managed server ", server.getName() - dumpStack() -serverConfig() -disconnect() -EOF - sudo chown -R ${userOracle}:${groupOracle} ${SCRIPT_PATH} - runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST ${SCRIPT_PATH}/restart-managedServer.py" - - if [[ $? != 0 ]]; then - echo "Error : Fail to restart managed server to sync up elk configuration." - exit 1 - fi -} - -#This function to check admin server status -function wait_for_admin() { - #check admin server status - count=1 - CHECK_URL="http://$wlsAdminURL/weblogic/ready" - status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) - echo "Check admin server status" - while [[ "$status" != "200" ]]; do - echo "." - count=$((count + 1)) - if [ $count -le 30 ]; then - sleep 1m - else - echo "Error : Maximum attempts exceeded while checking admin server status" - exit 1 - fi - status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) - if [ "$status" == "200" ]; then - echo "WebLogic Server is running..." - break - fi - done -} - -# shutdown admin server -function shutdown_admin() { - #check admin server status - count=1 - CHECK_URL="http://$wlsAdminURL/weblogic/ready" - status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) - echo "Check admin server status" - while [[ "$status" == "200" ]]; do - echo "." - count=$((count + 1)) - sudo systemctl stop wls_admin - if [ $count -le 30 ]; then - sleep 1m - else - echo "Error : Maximum attempts exceeded while stopping admin server" - exit 1 - fi - status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) - if [ -z ${status} ]; then - echo "WebLogic Server is stop..." - break - fi - done -} - -function cleanup() { - echo "Cleaning up temporary files..." - rm -f -r ${SCRIPT_PATH} - echo "Cleanup completed." -} - -function create_temp_folder() -{ - SCRIPT_PATH="/u01/tmp" - sudo rm -f -r ${SCRIPT_PATH} - sudo mkdir ${SCRIPT_PATH} - sudo rm -rf $SCRIPT_PATH/* -} - -function validate_elastic_server() -{ - timestamp=$(date +%s) - testIndex="${logIndex}-validate-elk-server-from-server-${index}-${timestamp}" - output=$(curl -XPUT --user ${elasticUserName}:${elasticPassword} ${elasticURI}/${testIndex}) - if [[ $? -eq 1 || -z `echo $output | grep "\"acknowledged\":true"` ]];then - echo $output - exit 1 - fi - - count=1 - status404="\"status\":404" - while [[ -n ${status404} ]]; do - echo "." - count=$((count + 1)) - # remove the test index - echo "Removing test index..." - curl -XDELETE --user ${elasticUserName}:${elasticPassword} ${elasticURI}/${testIndex} - echo "Checking if test index is removed." - status404=$(curl -XGET --user ${elasticUserName}:${elasticPassword} ${elasticURI}/${testIndex} | grep "\"status\":404") - echo ${status404} - if [[ -n ${status404} ]]; then - echo "Test index is removed..." - break - fi - - if [ $count -le 30 ]; then - sleep 1m - else - echo "Error : Maximum attempts exceeded while removing test index from elastic server" - exit 1 - fi - done -} - -# main script starts from here - -SCRIPT_PWD=$(pwd) - -# store arguments in a special array -#args=("$@") -# get number of elements -#ELEMENTS=${#args[@]} - -# echo each element in array -# for loop -#for ((i = 0; i < $ELEMENTS; i++)); do -# echo "ARG[${args[${i}]}]" -#done - -read oracleHome wlsAdminURL wlsUserName wlsPassword wlsAdminServerName elasticURI elasticUserName elasticPassword wlsDomainName wlsDomainPath logsToIntegrate index logIndex managedServerPrefix - -hostName=$(hostname) -userOracle="oracle" -groupOracle="oracle" - -create_temp_folder -validate_input -validate_elastic_server - -echo "start to configure ELK" -setup_javahome - -if [ $index -eq 0 ]; then - create_wls_log_model - configure_wls_log - restart_admin_service - restartManagedServers -fi - -remove_logstash -install_logstash -configure_lostash -start_logstash -cleanup diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/elkIntegrationForDynamicCluster.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/elkIntegrationForDynamicCluster.sh deleted file mode 100644 index 4e675939f..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/elkIntegrationForDynamicCluster.sh +++ /dev/null @@ -1,927 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# -#Function to output message to StdErr -function echo_stderr() { - echo "$@" >&2 -} - -#Function to display usage message -function usage() { - echo_stderr "./elkIntegrationForDynamicCluster.sh <<< \"\"" -} - -function validate_input() { - if [ -z "$oracleHome" ]; then - echo_stderr "oracleHome is required. " - exit 1 - fi - - if [ -z "$wlsAdminURL" ]; then - echo_stderr "wlsAdminURL is required. " - exit 1 - fi - - if [ -z "$managedServerPrefix" ]; then - echo_stderr "managedServerPrefix is required. " - exit 1 - fi - - if [[ -z "$wlsUserName" || -z "$wlsPassword" ]]; then - echo_stderr "wlsUserName or wlsPassword is required. " - exit 1 - fi - - if [ -z "$wlsAdminServerName" ]; then - echo_stderr "wlsAdminServerName is required. " - exit 1 - fi - - if [ -z "$elasticURI" ]; then - echo_stderr "elasticURI is required. " - exit 1 - fi - - if [[ -z "$elasticUserName" || -z "$elasticPassword" ]]; then - echo_stderr "elasticUserName or elasticPassword is required. " - exit 1 - fi - - if [ -z "$wlsDomainName" ]; then - echo_stderr "wlsDomainName is required. " - exit 1 - fi - - if [ -z "$wlsDomainPath" ]; then - echo_stderr "wlsDomainPath is required. " - exit 1 - fi - - if [ -z "$index" ]; then - echo_stderr "index is required. " - exit 1 - fi - - if [ -z "$logsToIntegrate" ]; then - echo_stderr "logsToIntegrate is required. " - exit 1 - fi - - if [ -z "$logIndex" ]; then - echo_stderr "logIndex is required. " - exit 1 - fi - - if [ -z "$maxDynamicClusterSize" ]; then - echo_stderr "maxDynamicClusterSize is required. " - exit 1 - fi -} - -# Set access log with format: date time time-taken bytes c-ip s-ip c-dns s-dns cs-method cs-uri sc-status sc-comment ctx-ecid -# Redirect stdout logging enabled: true -# Redirect stderr logging enabled: true -# Stack Traces to stdout: true -function create_wls_log_model() { - cat <${SCRIPT_PATH}/configure-wls-log.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') -shutdown('$clusterName', 'Cluster') -try: - edit("$hostName") - startEdit() - cd('/Servers/${wlsAdminServerName}/WebServer/${wlsAdminServerName}/WebServerLog/${wlsAdminServerName}') - cmo.setLogFileFormat('extended') - cmo.setELFFields('date time time-taken bytes c-ip s-ip c-dns s-dns cs-method cs-uri sc-status sc-comment ctx-ecid ctx-rid') - - cd('/Servers/${wlsAdminServerName}/Log/${wlsAdminServerName}') - cmo.setRedirectStderrToServerLogEnabled(true) - cmo.setRedirectStdoutToServerLogEnabled(true) - cmo.setStdoutLogStack(true) - - cd('/ServerTemplates/${serverTemplate}/WebServer/${serverTemplate}/WebServerLog/${serverTemplate}') - cmo.setLogFileFormat('extended') - cmo.setELFFields('date time time-taken bytes c-ip s-ip c-dns s-dns cs-method cs-uri sc-status sc-comment ctx-ecid ctx-rid') - - cd('/ServerTemplates/${serverTemplate}/Log/${serverTemplate}') - cmo.setRedirectStderrToServerLogEnabled(true) - cmo.setRedirectStdoutToServerLogEnabled(true) - cmo.setStdoutLogStack(true) - - save() - resolve() - activate() -except: - stopEdit('y') - sys.exit(1) -destroyEditSession("$hostName",force = true) -try: - start('$clusterName', 'Cluster') -except: - dumpStack() -disconnect() -EOF -} - -# Remove existing Logstash -function remove_logstash() { - sudo systemctl status logstash - if [ $? -ne 0 ]; then - sudo systemctl stop logstash - fi - - sudo yum remove -y -v logstash - if [ $? -ne 0 ]; then - echo_stderr "Fail to remove existing Logstash." - exit 1 - fi -} - -# Install Logstash -function install_logstash() { - sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch - - cat </etc/yum.repos.d/logstash.repo -[logstash-7.x] -name=Elastic repository for 7.x packages -baseurl=https://artifacts.elastic.co/packages/7.x/yum -gpgcheck=1 -gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch -enabled=1 -autorefresh=1 -type=rpm-md -EOF - sudo yum install -y -v logstash - if [ ! -d "/usr/share/logstash" ]; then - echo_stderr "Fail to install Logstash." - exit 1 - fi -} - -# Start Logstash service -function start_logstash() { - sudo systemctl enable logstash - sudo systemctl daemon-reload - - #Start logstash - attempt=1 - while [[ $attempt -lt 4 ]]; do - echo "Starting logstash service attempt $attempt" - sudo systemctl start logstash - attempt=$(expr $attempt + 1) - sudo systemctl status logstash | grep running - if [[ $? == 0 ]]; then - echo "logstash service started successfully" - break - fi - sleep 1m - done -} - -function watch_server_log() { - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { -EOF - - if [ $index -eq 0 ]; then - serverName=$wlsAdminServerName - wlsLogPath="${wlsDomainPath}/servers/${serverName}/logs" - cat <>/etc/logstash/conf.d/weblogic-logs.conf - path => "${wlsLogPath}/${serverName}.log" -EOF - else - cat <>/etc/logstash/conf.d/weblogic-logs.conf - path => [ -EOF - count=1 - while [ $count -le $maxDynamicClusterSize ]; do - serverName=${managedServerPrefix}${count} - wlsLogPath="${wlsDomainPath}/servers/${serverName}/logs" - if [ $count == $maxDynamicClusterSize ]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - "${wlsLogPath}/${serverName}.log" - ] -EOF - else - cat <>/etc/logstash/conf.d/weblogic-logs.conf - "${wlsLogPath}/${serverName}.log", -EOF - fi - count=$((count + 1)) - done - fi - - cat <>/etc/logstash/conf.d/weblogic-logs.conf - codec => multiline { - pattern => "^####" - negate => true - what => "previous" - } - start_position => beginning - } -EOF -} - -function watch_access_log() { - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { -EOF - if [ $index -eq 0 ]; then - serverName=$wlsAdminServerName - wlsLogPath="${wlsDomainPath}/servers/${serverName}/logs" - cat <>/etc/logstash/conf.d/weblogic-logs.conf - path => "${wlsLogPath}/access.log" -EOF - else - cat <>/etc/logstash/conf.d/weblogic-logs.conf - path => [ -EOF - count=1 - while [ $count -le $maxDynamicClusterSize ]; do - serverName=${managedServerPrefix}${count} - wlsLogPath="${wlsDomainPath}/servers/${serverName}/logs" - if [ $count == $maxDynamicClusterSize ]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - "${wlsLogPath}/access.log" - ] -EOF - else - cat <>/etc/logstash/conf.d/weblogic-logs.conf - "${wlsLogPath}/access.log", -EOF - fi - count=$((count + 1)) - done - fi - - cat <>/etc/logstash/conf.d/weblogic-logs.conf - start_position => beginning - } -EOF -} - -function watch_domain_log() { - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { -EOF - if [ $index -eq 0 ]; then - serverName=$wlsAdminServerName - wlsLogPath="${wlsDomainPath}/servers/${serverName}/logs" - cat <>/etc/logstash/conf.d/weblogic-logs.conf - path => "${wlsLogPath}/${wlsDomainName}.log" -EOF - else - cat <>/etc/logstash/conf.d/weblogic-logs.conf - path => [ -EOF - count=1 - while [ $count -le $maxDynamicClusterSize ]; do - serverName=${managedServerPrefix}${count} - wlsLogPath="${wlsDomainPath}/servers/${serverName}/logs" - if [ $count == $maxDynamicClusterSize ]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - "${wlsLogPath}/${serverTemplate}.log" - ] -EOF - else - cat <>/etc/logstash/conf.d/weblogic-logs.conf - "${wlsLogPath}/${serverTemplate}.log", -EOF - fi - count=$((count + 1)) - done - fi - - cat <>/etc/logstash/conf.d/weblogic-logs.conf - codec => multiline { - pattern => "^####" - negate => true - what => "previous" - } - start_position => beginning - } -EOF -} - -function watch_std_log() { - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { -EOF - if [ $index -eq 0 ]; then - serverName=$wlsAdminServerName - wlsLogPath="${wlsDomainPath}/servers/${serverName}/logs" - cat <>/etc/logstash/conf.d/weblogic-logs.conf - path => "${wlsLogPath}/${serverName}.out" -EOF - else - cat <>/etc/logstash/conf.d/weblogic-logs.conf - path => [ -EOF - count=1 - while [ $count -le $maxDynamicClusterSize ]; do - serverName=${managedServerPrefix}${count} - wlsLogPath="${wlsDomainPath}/servers/${serverName}/logs" - if [ $count == $maxDynamicClusterSize ]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - "${wlsLogPath}/${serverName}.out" - ] -EOF - else - cat <>/etc/logstash/conf.d/weblogic-logs.conf - "${wlsLogPath}/${serverName}.out", -EOF - fi - count=$((count + 1)) - done - fi - - cat <>/etc/logstash/conf.d/weblogic-logs.conf - codec => multiline { - pattern => "^<" - negate => true - what => "previous" - } - start_position => beginning - } -EOF -} - -function watch_ds_log() { - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { -EOF - if [ $index -eq 0 ]; then - serverName=$wlsAdminServerName - wlsLogPath="${wlsDomainPath}/servers/${serverName}/logs" - cat <>/etc/logstash/conf.d/weblogic-logs.conf - path => "${wlsLogPath}/datasource.log" -EOF - else - cat <>/etc/logstash/conf.d/weblogic-logs.conf - path => [ -EOF - count=1 - while [ $count -le $maxDynamicClusterSize ]; do - serverName=${managedServerPrefix}${count} - wlsLogPath="${wlsDomainPath}/servers/${serverName}/logs" - if [ $count == $maxDynamicClusterSize ]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - "${wlsLogPath}/datasource.log" - ] -EOF - else - cat <>/etc/logstash/conf.d/weblogic-logs.conf - "${wlsLogPath}/datasource.log", -EOF - fi - count=$((count + 1)) - done - fi - - cat <>/etc/logstash/conf.d/weblogic-logs.conf - codec => multiline { - pattern => "^####" - negate => true - what => "previous" - } - start_position => beginning - } -EOF -} - -# Configure Logstash: -# * grok patterns -> /etc/logstash/patterns/weblogic-logstash-patterns.txt -# * conf files -> /etc/logstash/conf.d -# * JAVA_HOME -> /etc/logstash/startup.options -# * create logstash start up -# Examples for patterns: -# * ACCESSDATE -# * parse date of access -# * 2020-09-01 -# * DBDATETIME -# * parse data source datetime -# * Tue Sep 01 05:05:41 UTC 2020 -# * DSIDORTIMESTAMP -# * parse data source dynamic fields: id | timestamp, one of them exists. -# * timestamp: Tue Sep 01 05:05:41 UTC 2020 -# * id: 64 -# * DSPARTITION -# * parse partition info. -# * [partition-name: DOMAIN] [partition-id: 0] -# * [partition-id: 0] [partition-name: DOMAIN] -# * DSWEBLOGICMESSAGE -# * parse data source user id or error messsage. -# * error: Java stack trace -# * user id: -# * WEBLOGICDIAGMESSAGE -# * parse domain log message. -# * e.g. Java stack trace -# * e.g. Self-tuning thread pool contains 0 running threads, 2 idle threads, and 13 standby threads -# * WEBLOGICDOMAINDATE -# * parse domain|server log datetime. -# * from wls 14: Sep 1, 2020, 5:41:51,040 AM Coordinated Universal Time -# * from wls 12: Sep 1, 2020 5:41:51,040 AM Coordinated Universal Time -# * WEBLOGICLOGPARTITION -# * parse partition info in domain log. -# * [severity-value: 64] -# * [severity-value: 64] [rid: 0] -# * [severity-value: 64] [partition-id: 0] [partition-name: DOMAIN ] -# * [severity-value: 64] [rid: 0] [partition-id: 0] [partition-name: DOMAIN ] -# * WEBLOGICSERVERLOGPARTITION -# * parse partition info in server log. -# * [severity-value: 64] -# * [severity-value: 64] [rid: 0] -# * [severity-value: 64] [partition-id: 0] [partition-name: DOMAIN ] -# * [severity-value: 64] [rid: 0] [partition-id: 0] [partition-name: DOMAIN ] -# * WEBLOGICSERVERRID -# * parse dynamic filed rid in server log. -# * [rid: 0] -# * WEBLOGICSERVERMESSAGE -# * parse field message in server log. -# * e.g. Java stack trace -# * e.g. Self-tuning thread pool contains 0 running threads, 2 idle threads, and 13 standby threads -# * WEBLOGICSTDDATE -# * parse field date in std log. -# * Aug 31, 2020 5:37:27,646 AM UTC -# * Aug 31, 2020 5:37:27 AM UTC -function configure_lostash() { - echo "create patterns" - rm -f -r /etc/logstash/patterns - if [ -d "/etc/logstash/patterns" ]; then - rm -f /etc/logstash/patterns/weblogic-logstash-patterns.txt - else - mkdir /etc/logstash/patterns - fi - cat </etc/logstash/patterns/weblogic-logstash-patterns.txt -ACCESSDATE ^\d{4}[./-]%{MONTHNUM}[./-]%{MONTHDAY} -DBDATETIME %{DAY} %{MONTH:db_month} %{MONTHDAY:db_day} %{HOUR:db_hour}:%{MINUTE:db_minute}:%{SECOND:db_second} %{TZ:db_tz} %{YEAR:db_year} -DSIDORTIMESTAMP (?(\b(?:[1-9][0-9]*)\b))|%{DBDATETIME:ds_timestamp} -DSPARTITION (?:\[partition-id: %{INT:ds_partitionId}\] \[partition-name: %{DATA:ds_partitionName}\]\s)|(?:\[partition-name: %{DATA:ds_partitionName}\] \[partition-id: %{INT:ds_partitionId}\]\s) -DSWEBLOGICMESSAGE (?(.|\r|\n)*)|%{GREEDYDATA:ds_user} -JAVAPACKAGE ([a-zA-Z_$][a-zA-Z\d_$]*\.)*[a-zA-Z_$][a-zA-Z\d_$]* -NODEMANAGERMESSAGE (?(.|\r|\n[^A-Za-z0-9])*)|%{GREEDYDATA:node_message} -NODEMANAGEREND (<%{WORDNOSPACES:node_domain}>\s<%{WORDNOSPACES:node_server}>\s<%{NODEMANAGERMESSAGE}>)|(<%{GREEDYDATA:node_messageType}>\s<%{NODEMANAGERMESSAGE}>)|<%{NODEMANAGERMESSAGE}> -WEBLOGICDIAGMESSAGE (?(.|\r|\n)*)|%{GREEDYDATA:diag_message} -WEBLOGICDOMAINDATE %{MONTH:tmp_month} %{MONTHDAY:tmp_day}, %{YEAR:tmp_year},? %{HOUR:tmp_hour}:%{MINUTE:tmp_min}:%{SECOND:tmp_second},(?([0-9]{3})) (?(AM|PM)) -WEBLOGICLOGPARTITION (?:\s\[rid: %{DATA:diag_rid}\] \[partition-id: %{INT:diag_partitionId}\] \[partition-name: %{DATA:diag_partitionName}\]\s)|(?:\s\[partition-id: %{INT:diag_partitionId}\] \[partition-name: %{DATA:diag_partitionName}\]\s)|(?:\s\[rid: %{DATA:diag_rid}\]\s)|(\s) -WEBLOGICSERVERLOGPARTITION (?:\s\[rid: %{DATA:log_rid}\] \[partition-id: %{INT:log_partitionId}\] \[partition-name: %{DATA:log_partitionName}\]\s)|(?:\s\[partition-id: %{INT:log_partitionId}\] \[partition-name: %{DATA:log_partitionName}\]\s)|(?:\s\[rid: %{DATA:log_rid}\]\s)|(\s) -WEBLOGICSERVERRID (?:\s\[rid: %{WORDNOSPACES:log_rid}\]\s)|(\s) -WEBLOGICSERVERMESSAGE (?(.|\r|\n)*)|%{GREEDYDATA:log_message} -WEBLOGICSTDDATE %{MONTH:tmp_month} %{MONTHDAY:tmp_day}, %{YEAR:tmp_year},? %{HOUR:tmp_hour}:%{MINUTE:tmp_min}:%{SECOND:tmp_second} (?(AM|PM)) -WEBLOGICSTDMESSAGE (?(.|\r|\n[^A-Za-z0-9])*)|%{GREEDYDATA:out_message} -WEBLOGICSTDDYNAMICID (<%{WORDNOSPACES:out_messageId}>\s<%{WEBLOGICSTDMESSAGE}>)|<%{WEBLOGICSTDMESSAGE}> -WORDNOSPACES [^ ]* -WORDNOBRACKET [^\]]* -WORDWITHSPACE (\b\w+\b|\s)* -EOF - - if [ $index -eq 0 ]; then - serverName=$wlsAdminServerName - else - serverName=${managedServerPrefix}${index} - fi - wlsLogPath="${wlsDomainPath}/servers/${serverName}/logs" - privateIP=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/') - - rm -f /etc/logstash/conf.d/weblogic-logs.conf - cat </etc/logstash/conf.d/weblogic-logs.conf -input { -EOF - - if [[ -n $(echo ${logsToIntegrate} | grep "HTTPAccessLog") ]]; then - watch_access_log - fi - - if [[ -n $(echo ${logsToIntegrate} | grep "ServerLog") ]]; then - watch_server_log - fi - - if [[ -n $(echo ${logsToIntegrate} | grep "DomainLog") ]]; then - watch_domain_log - fi - - if [[ -n $(echo ${logsToIntegrate} | grep "DataSourceLog") ]]; then - watch_ds_log - fi - - if [[ -n $(echo ${logsToIntegrate} | grep "StandardErrorAndOutput") ]]; then - watch_std_log - fi - - if [[ -n $(echo ${logsToIntegrate} | grep "NodeManagerLog") ]]; then - cat <>/etc/logstash/conf.d/weblogic-logs.conf - file { - path => "${wlsDomainPath}/nodemanager/nodemanager.log" - codec => multiline { - pattern => "^<" - negate => true - what => "previous" - } - start_position => beginning - } -EOF - fi - - cat <>/etc/logstash/conf.d/weblogic-logs.conf -} -filter { - grok { - match => {"path" => "%{GREEDYDATA}/%{GREEDYDATA:type}"} - } - mutate { - add_field => { "internal_ip" => "${privateIP}" } - } - - if [type] == "${wlsAdminServerName}.log" or [type] =~ /^${managedServerPrefix}\d+.log/ { - mutate { replace => { type => "weblogic_server_log" } } - # match rid - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "####<%{WEBLOGICDOMAINDATE}%{SPACE}%{GREEDYDATA:log_timezone}>%{SPACE}<%{LOGLEVEL:log_severity}>%{SPACE}<%{GREEDYDATA:log_subSystem}>%{SPACE}<%{HOSTNAME:log_machine}>%{SPACE}<%{DATA:log_server}>%{SPACE}<%{DATA:log_thread}>%{SPACE}<%{DATA:log_userId}>%{SPACE}<%{DATA:log_transactionId}>%{SPACE}<%{DATA:log_contextId}>%{SPACE}<%{NUMBER:log_timestamp}>%{SPACE}<\[severity-value: %{INT:log_severityValue}\]%{WEBLOGICSERVERLOGPARTITION}>%{SPACE}<%{DATA:log_massageId}>%{SPACE}<%{WEBLOGICSERVERMESSAGE}>" ] - } - - mutate { - replace => ['log_date', '%{tmp_month} %{tmp_day}, %{tmp_year} %{tmp_hour}:%{tmp_min}:%{tmp_second},%{tmp_sss} %{tmp_aa}'] - } - - translate { - field => 'log_timezone' - destination => 'log_timezone' - fallback => '%{log_timezone}' - override => "true" - dictionary => { - "Coordinated Universal Time" => "UTC" - } - } - - date { - match => [ "log_date", "MMM dd, YYYY KK:mm:ss,SSS aa", "MMM d, YYYY KK:mm:ss,SSS aa"] - timezone => "%{log_timezone}" - target => "log_date" - } - mutate { - remove_field => [ 'log_timezone', 'tmp_month', 'tmp_day', 'tmp_year', 'tmp_hour', 'tmp_min', 'tmp_second', 'tmp_sss', 'tmp_aa'] - } - } - else if [type] == "access.log" { - # drop message starting with # - if [message] =~ /^#/ { - drop {} - } - mutate { replace => { type => "weblogic_access_log" } } - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "%{ACCESSDATE:acc_date}\s+%{TIME:acc_time}\s+%{NUMBER:time_taken}\s+%{NUMBER:bytes:int}\s+%{IP:c_ip}\s+%{HOSTPORT:s_ip}\s+%{IPORHOST:c_dns}\s+%{IPORHOST:s_dns}\s+%{WORD:cs_method}\s+%{URIPATHPARAM:cs_uri}\s+%{NUMBER:sc_status}\s+%{QUOTEDSTRING:sc-comment}\s+%{WORDNOSPACES:ctx-ecid}\s+%{WORDNOSPACES:ctx-rid}" ] - } - mutate { - replace => ['acc_timestamp', '%{acc_date} %{acc_time}'] - } - date { - match => [ "acc_timestamp" , "yyyy-MM-dd HH:mm:ss" ] - timezone => "UTC" - target => "acc_timestamp" - } - mutate { - remove_field => [ 'acc_date', 'acc_time'] - } - } - else if [type] == "${wlsDomainName}.log" or [type] == "${serverTemplate}.log" { - mutate { replace => { type => "weblogic_domain_log" } } - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "####<%{WEBLOGICDOMAINDATE}%{SPACE}%{GREEDYDATA:diag_timezone}>%{SPACE}<%{LOGLEVEL:diag_severity}>%{SPACE}<%{GREEDYDATA:diag_subSystem}>%{SPACE}<%{HOSTNAME:diag_machine}>%{SPACE}<%{HOSTNAME:diag_server}>%{SPACE}<%{DATA:diag_thread}>%{SPACE}<%{WORDNOBRACKET:diag_userId}>%{SPACE}<%{DATA:diag_transactionId}>%{SPACE}<%{WORDNOSPACES:diag_contextId}>%{SPACE}<%{NUMBER:diag_timestamp}>%{SPACE}<\[severity-value: %{INT:diag_severityValue}\]%{WEBLOGICLOGPARTITION}>%{SPACE}<%{DATA:diag_massageId}>%{SPACE}<%{WEBLOGICDIAGMESSAGE}>" ] - } - - mutate { - replace => ['diag_date', '%{tmp_month} %{tmp_day}, %{tmp_year} %{tmp_hour}:%{tmp_min}:%{tmp_second},%{tmp_sss} %{tmp_aa}'] - } - - translate { - field => 'diag_timezone' - destination => 'diag_timezone' - fallback => '%{diag_timezone}' - override => "true" - dictionary => { - "Coordinated Universal Time" => "UTC" - } - } - - date { - match => [ "diag_date", "MMM dd, YYYY KK:mm:ss,SSS aa", "MMM d, YYYY KK:mm:ss,SSS aa"] - timezone => "%{diag_timezone}" - target => "diag_date" - } - mutate { - remove_field => [ 'diag_timezone', 'tmp_month', 'tmp_day', 'tmp_year', 'tmp_hour', 'tmp_min', 'tmp_second', 'tmp_sss', 'tmp_aa'] - } - } - else if [type] == "datasource.log" { - mutate { replace => { type => "weblogic_datasource_log" } } - # with timestamp - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "####<%{WORDNOSPACES:ds_dataSource}>%{SPACE}<%{WORDNOSPACES:ds_profileType}>%{SPACE}<%{DSIDORTIMESTAMP}>%{SPACE}<%{DSWEBLOGICMESSAGE}>%{SPACE}<%{DATA:ds_info}>%{SPACE}<%{DSPARTITION}>" ] - } - - if ([db_month]) { - # DBDATETIME %{DAY} %{MONTH:db_month} %{MONTHDAY:db_day} %{HOUR:db_hour}:%{MINUTE:db_minute}:%{SECOND:db_second} %{TZ:db_tz} %{YEAR:db_year} - mutate { - replace => ["ds_timestamp", "%{db_month} %{db_day}, %{db_year} %{db_hour}:%{db_minute}:%{db_second}"] - } - - date { - match => [ "ds_timestamp", "MMM dd, YYYY HH:mm:ss", "MMM d, YYYY HH:mm:ss"] - timezone => "%{db_tz}" - target => "ds_timestamp" - } - mutate { - remove_field => [ 'db_month','db_day','db_year','db_hour','db_minute','db_second','db_tz'] - } - } - } - else if [type] == "${wlsAdminServerName}.out" or [type] =~ /^${managedServerPrefix}\d+.out/ { - mutate { replace => { type => "weblogic_std_log" } } - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "<%{WEBLOGICSTDDATE}%{SPACE}%{WORDWITHSPACE:out_timezone}>%{SPACE}<%{WORDWITHSPACE:out_level}>%{SPACE}<%{WORDWITHSPACE:out_subsystem}>%{SPACE}%{WEBLOGICSTDDYNAMICID}"] - } - - mutate { - replace => ['out_timestamp', '%{tmp_month} %{tmp_day}, %{tmp_year} %{tmp_hour}:%{tmp_min}:%{tmp_second} %{tmp_aa}'] - } - - # CEST id does not exist in JODA-TIME, changed to CET - translate { - field => 'out_timezone' - destination => 'out_timezone' - fallback => '%{out_timezone}' - override => "true" - dictionary => { - "CEST" => "CET" - "Coordinated Universal Time" => "UTC" - } - } - - date { - match => [ "out_timestamp", "MMM dd, YYYY KK:mm:ss aa", "MMM d, YYYY KK:mm:ss aa", "MMM dd, YYYY KK:mm:ss,SSS aa", "MMM d, YYYY KK:mm:ss,SSS aa"] - timezone => "%{out_timezone}" - target => "out_timestamp" - } - mutate { - remove_field => [ 'out_timezone','tmp_month', 'tmp_day', 'tmp_year', 'tmp_hour', 'tmp_min', 'tmp_second', 'tmp_aa'] - } - } - else if [type] == "nodemanager.log" { - mutate { replace => { type => "weblogic_nodemanager_log" } } - grok { - patterns_dir=> ["/etc/logstash/patterns"] - match => [ "message", "<%{WEBLOGICSTDDATE}%{SPACE}%{WORDWITHSPACE:node_timezone}>%{SPACE}<%{WORDWITHSPACE:node_level}>%{SPACE}%{NODEMANAGEREND}"] - } - - mutate { - replace => ['node_timestamp', '%{tmp_month} %{tmp_day}, %{tmp_year} %{tmp_hour}:%{tmp_min}:%{tmp_second} %{tmp_aa}'] - } - - # CEST id does not exist in JODA-TIME, changed to CET - translate { - field => 'node_timezone' - destination => 'node_timezone' - fallback => '%{node_timezone}' - override => "true" - dictionary => { - "CEST" => "CET" - "Coordinated Universal Time" => "UTC" - } - } - - date { - match => [ "node_timestamp", "MMM dd, YYYY KK:mm:ss aa", "MMM d, YYYY KK:mm:ss aa", "MMM dd, YYYY KK:mm:ss,SSS aa", "MMM d, YYYY KK:mm:ss,SSS aa"] - timezone => "%{node_timezone}" - target => "node_timestamp" - } - mutate { - remove_field => [ 'node_timezone','tmp_month', 'tmp_day', 'tmp_year', 'tmp_hour', 'tmp_min', 'tmp_second', 'tmp_aa'] - } - } -} -output { - elasticsearch { - hosts => "${elasticURI}" - user => "${elasticUserName}" - password => "${elasticPassword}" - index => "${logIndex}" - } -} -EOF - - # Add JAVA_HOME to startup.options - cp /etc/logstash/startup.options /etc/logstash/startup.options.elksave - sed -i -e "/JAVACMD/a\\JAVA_HOME=${JAVA_HOME}" /etc/logstash/startup.options - sed -i -e "s:LS_USER=.*:LS_USER=${userOracle}:g" /etc/logstash/startup.options - sed -i -e "s:LS_GROUP=.*:LS_GROUP=${groupOracle}:g" /etc/logstash/startup.options - - # For Java 11 - # ISSUE: https://github.com/elastic/logstash/issues/10496 - java_version=$(java -version 2>&1 | sed -n ';s/.* version "\(.*\)\.\(.*\)\..*"/\1\2/p;') - if [ ${java_version:0:3} -ge 110 ]; then - cp /etc/logstash/jvm.options /etc/logstash/jvm.options.elksave - cat <>/etc/logstash/jvm.options ---add-opens java.base/sun.nio.ch=org.jruby.dist ---add-opens java.base/java.io=org.jruby.dist -EOF - fi - - # create start up for logstash - /usr/share/logstash/bin/system-install /etc/logstash/startup.options - if [ $? -ne 0 ]; then - echo_stderr "Failed to set up logstash service." - exit 1 - fi - - sudo chown -R ${userOracle}:${groupOracle} /var/lib/logstash - sudo chown -R ${userOracle}:${groupOracle} /etc/logstash -} - -function configure_wls_log() { - echo "Configure WebLogic Log" - sudo chown -R ${userOracle}:${groupOracle} ${SCRIPT_PATH} - runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST ${SCRIPT_PATH}/configure-wls-log.py" - - errorCode=$? - if [ $errorCode -eq 1 ]; then - echo "Exception occurs during ELK configuration, please check." - exit 1 - fi -} - -function setup_javahome() { - . $oracleHome/oracle_common/common/bin/setWlstEnv.sh -} - -function restart_admin_service() { - echo "Restart weblogic admin server" - echo "Stop admin server" - shutdown_admin - sudo systemctl start wls_admin - echo "Waiting for admin server to be available" - wait_for_admin - echo "Weblogic admin server is up and running" -} - -function restart_cluster() { - cat <${SCRIPT_PATH}/restart-cluster.py -# Connect to the AdminServer. -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') -print "Restart cluster." -try: - print "Shutdown cluster." - shutdown('$clusterName', 'Cluster') - print "Start cluster." - start('$clusterName', 'Cluster') -except: - dumpStack() - -disconnect() -EOF - - sudo chown -R ${userOracle}:${groupOracle} ${SCRIPT_PATH} - runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST ${SCRIPT_PATH}/restart-cluster.py" - errorCode=$? - if [ $errorCode -eq 1 ]; then - echo "Failed to restart cluster." - exit 1 - fi -} - -#This function to check admin server status -function wait_for_admin() { - #check admin server status - count=1 - CHECK_URL="http://$wlsAdminURL/weblogic/ready" - status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) - echo "Check admin server status" - while [[ "$status" != "200" ]]; do - echo "." - count=$((count + 1)) - if [ $count -le 30 ]; then - sleep 1m - else - echo "Error : Maximum attempts exceeded while checking admin server status" - exit 1 - fi - status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) - if [ "$status" == "200" ]; then - echo "WebLogic Server is running..." - break - fi - done -} - -# shutdown admin server -function shutdown_admin() { - #check admin server status - count=1 - CHECK_URL="http://$wlsAdminURL/weblogic/ready" - status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) - echo "Check admin server status" - while [[ "$status" == "200" ]]; do - echo "." - count=$((count + 1)) - sudo systemctl stop wls_admin - if [ $count -le 30 ]; then - sleep 1m - else - echo "Error : Maximum attempts exceeded while stopping admin server" - exit 1 - fi - status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) - if [ -z ${status} ]; then - echo "WebLogic Server is stop..." - break - fi - done -} - -function cleanup() { - echo "Cleaning up temporary files..." - rm -f -r ${SCRIPT_PATH} - echo "Cleanup completed." -} - -function create_temp_folder() -{ - SCRIPT_PATH="/u01/tmp" - sudo rm -f -r ${SCRIPT_PATH} - sudo mkdir ${SCRIPT_PATH} - sudo rm -rf $SCRIPT_PATH/* -} - -function validate_elastic_server() -{ - timestamp=$(date +%s) - testIndex="${logIndex}-validate-elk-server-from-server-${index}-${timestamp}" - output=$(curl -XPUT --user ${elasticUserName}:${elasticPassword} ${elasticURI}/${testIndex}) - if [[ $? -eq 1 || -z `echo $output | grep "\"acknowledged\":true"` ]];then - echo $output - exit 1 - fi - - count=1 - status404="\"status\":404" - while [[ -n ${status404} ]]; do - echo "." - count=$((count + 1)) - # remove the test index - echo "Removing test index..." - curl -XDELETE --user ${elasticUserName}:${elasticPassword} ${elasticURI}/${testIndex} - echo "Checking if test index is removed." - status404=$(curl -XGET --user ${elasticUserName}:${elasticPassword} ${elasticURI}/${testIndex} | grep "\"status\":404") - echo ${status404} - if [[ -n ${status404} ]]; then - echo "Test index is removed..." - break - fi - - if [ $count -le 30 ]; then - sleep 1m - else - echo "Error : Maximum attempts exceeded while removing test index from elastic server" - exit 1 - fi - done -} - -#main script starts here - -SCRIPT_PWD=$(pwd) - -read oracleHome wlsAdminURL managedServerPrefix wlsUserName wlsPassword wlsAdminServerName elasticURI elasticUserName elasticPassword wlsDomainName wlsDomainPath logsToIntegrate index logIndex maxDynamicClusterSize - -hostName=$(hostname) -userOracle="oracle" -groupOracle="oracle" -clusterName="cluster1" -serverTemplate="myServerTemplate" - -create_temp_folder -validate_input -validate_elastic_server - -echo "start to configure ELK" -setup_javahome - -if [ $index -eq 0 ]; then - create_wls_log_model - configure_wls_log - restart_admin_service - echo "Waiting for admin server to be available" - wait_for_admin - echo "Weblogic admin server is up and running" - restart_cluster -fi - -remove_logstash -install_logstash -configure_lostash -start_logstash -cleanup diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/installJdbcDrivers.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/installJdbcDrivers.sh new file mode 100644 index 000000000..c88b06002 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/installJdbcDrivers.sh @@ -0,0 +1,254 @@ +# Copyright (c) 2021, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +# Description +# This script is to install jdbc libraries at WebLogic cluster domain. + +# /bin/bash + +#Function to output message to StdErr +function echo_stderr() { + echo "$@" >&2 +} + +#Function to display usage message +function usage() { + echo_stderr "./installJdbcDrivers.sh <<< \"\"" +} + +function validate_input() { + + # parse base64 string + wlsShibboleth=$(echo "${wlsShibboleth}" | base64 -d) + + if [ -z "$oracleHome" ]; then + echo _stderr "Please provide oracleHome" + exit 1 + fi + + if [ -z "$domainPath" ]; then + echo _stderr "Please provide domainPath" + exit 1 + fi + + if [ -z "$wlsServerName" ]; then + echo _stderr "Please provide wlsServerName" + exit 1 + fi + + if [ -z "$wlsAdminHost" ]; then + echo _stderr "Please provide wlsAdminHost" + exit 1 + fi + + if [ -z "$wlsAdminPort" ]; then + echo _stderr "Please provide wlsAdminPort" + exit 1 + fi + + if [ -z "$wlsUserName" ]; then + echo _stderr "Please provide wlsUserName" + exit 1 + fi + + if [ -z "$wlsShibboleth" ]; then + echo _stderr "Please provide wlsShibboleth" + exit 1 + fi + + if [ -z "$databaseType" ]; then + echo _stderr "Please provide databaseType" + exit 1 + fi + + if [ -z "$enablePswlessConnection" ]; then + echo _stderr "Please provide enablePswlessConnection" + exit 1 + fi +} + +function install_maven() { + sudo yum install maven -y +} + +function uninstall_maven() { + sudo yum remove maven -y +} + +function install_azure_identity_extension() { + local myPomFile=pom.xml + curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -fksL "${gitUrl4AzureIdentityExtensionPomFile}" -o ${myPomFile} + if [ $? != 0 ]; then + echo_stderr "Failed to download ${gitUrl4AzureIdentityExtensionPomFile}." + fi + + echo "download dependencies" + mvn dependency:copy-dependencies -f ${myPomFile} + if [ $? -eq 0 ]; then + ls -l target/dependency/ + + domainBase=$(dirname $domainPath) + + # check if azure identity extension has been installed, if so, remove old version + if [ -d "${domainBase}/azure-libraries/identity" ]; then + sudo rm ${domainBase}/azure-libraries/identity -f -r + sudo rm ${domainBase}/azure-libraries/jackson -f -r + fi + + sudo mkdir -p ${domainBase}/azure-libraries/identity + sudo mkdir -p ${domainBase}/azure-libraries/jackson + # fix JARs conflict issue, put jackson libraries to PRE_CLASSPATH to upgrade the existing libs. + sudo mv target/dependency/jackson-annotations-*.jar ${domainBase}/azure-libraries/jackson + sudo mv target/dependency/jackson-core-*.jar ${domainBase}/azure-libraries/jackson + sudo mv target/dependency/jackson-databind-*.jar ${domainBase}/azure-libraries/jackson + sudo mv target/dependency/jackson-dataformat-xml-*.jar ${domainBase}/azure-libraries/jackson + # Those jars will be appended to CLASSPATH + sudo mv target/dependency/*.jar ${domainBase}/azure-libraries/identity + sudo chown -R oracle:oracle ${domainBase}/azure-libraries + else + echo "Failed to download dependencies for azure-identity-extension" + exit 1 + fi + + rm ${myPomFile} -f + rm target -f -r + if ! grep -q "${domainBase}/azure-libraries/identity/" "${domainPath}/bin/setDomainEnv.sh"; then + sed -i 's;^export DOMAIN_HOME;&\nCLASSPATH="'${domainBase}'/azure-libraries/identity/*:${CLASSPATH}";' ${domainPath}/bin/setDomainEnv.sh + fi + + if ! grep -q "${domainBase}/azure-libraries/jackson/" "${domainPath}/bin/setDomainEnv.sh"; then + sed -i 's;^export DOMAIN_HOME;&\nPRE_CLASSPATH="'${domainBase}'/azure-libraries/jackson/*:${PRE_CLASSPATH}";' ${domainPath}/bin/setDomainEnv.sh + fi +} + +function upgrade_mysql_driver() { + local mysqlPomFile=mysql-pom.xml + curl -m ${curlMaxTime} --retry ${retryMaxAttempt} -fksL "${gitUrl4MySQLDriverPomFile}" -o ${mysqlPomFile} + if [ $? != 0 ]; then + echo_stderr "Failed to download ${gitUrl4MySQLDriverPomFile}." + fi + + echo "download dependencies" + mvn dependency:copy-dependencies -f ${mysqlPomFile} + if [ $? -eq 0 ]; then + ls -l target/dependency/ + + local domainBase=$(dirname $domainPath) + local preClassLibsFolderName=preclasspath-libraries + + # check if the driver has been upgraded, if so, remove old driver + if [ -e ${domainBase}/${preClassLibsFolderName}/mysql-connector-*.jar ]; then + sudo rm ${domainBase}/${preClassLibsFolderName} -f -r + fi + + sudo mkdir ${domainBase}/${preClassLibsFolderName} + sudo mv target/dependency/mysql-connector-*.jar ${domainBase}/${preClassLibsFolderName}/ + sudo chown -R oracle:oracle ${domainBase}/${preClassLibsFolderName} + else + echo "Failed to download mysql driver." + exit 1 + fi + + rm ${mysqlPomFile} -f + rm target -f -r + + if ! grep -q "${domainBase}/preclasspath-libraries/" "${domainPath}/bin/setDomainEnv.sh"; then + sed -i 's;^export DOMAIN_HOME;&\nPRE_CLASSPATH="'${domainBase}'/preclasspath-libraries/*:${PRE_CLASSPATH}";' ${domainPath}/bin/setDomainEnv.sh + fi +} + +#This function to wait for admin server +function wait_for_admin() { + #wait for admin to start + count=1 + CHECK_URL="http://$wlsAdminURL/weblogic/ready" + status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) + echo "Waiting for admin server to start" + while [[ "$status" != "200" ]]; do + echo "." + count=$((count + 1)) + if [ $count -le 30 ]; then + sleep 1m + else + echo "Error : Maximum attempts exceeded while starting admin server" + exit 1 + fi + status=$(curl --insecure -ILs $CHECK_URL | tac | grep -m1 HTTP/1.1 | awk {'print $2'}) + if [ "$status" == "200" ]; then + echo "Admin Server started succesfully..." + break + fi + done +} + +function restart_admin_service() { + echo "Restart weblogic admin server service" + sudo systemctl stop wls_admin + sudo systemctl start wls_admin + wait_for_admin +} + +function restart_managed_servers() { + echo "Restart managed servers" + cat <${SCRIPT_PWD}/restart-managedServer.py +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') +servers=cmo.getServers() +domainRuntime() +print "Restart the servers which are in RUNNING status" +for server in servers: + bean="/ServerLifeCycleRuntimes/"+server.getName() + serverbean=getMBean(bean) + if (serverbean.getState() in ("RUNNING")) and (server.getName() == '${wlsServerName}'): + try: + print "Stop the Server ",server.getName() + shutdown(server.getName(),server.getType(),ignoreSessions='true',force='true') + print "Start the Server ",server.getName() + start(server.getName(),server.getType()) + break + except: + print "Failed restarting managed server ", server.getName() + dumpStack() +serverConfig() +disconnect() +EOF + . $oracleHome/oracle_common/common/bin/setWlstEnv.sh + java $WLST_ARGS weblogic.WLST ${SCRIPT_PWD}/restart-managedServer.py + + if [[ $? != 0 ]]; then + echo "Error : Fail to restart managed server to configuration external libraries." + exit 1 + fi +} + +#read arguments from stdin +read oracleHome domainPath wlsServerName wlsAdminHost wlsAdminPort wlsUserName wlsShibboleth databaseType enablePswlessConnection + +export curlMaxTime=120 # seconds +export gitUrl4AzureIdentityExtensionPomFile="https://raw.githubusercontent.com/oracle/weblogic-azure/main/weblogic-azure-aks/src/main/resources/azure-identity-extensions.xml" +export gitUrl4MySQLDriverPomFile="https://raw.githubusercontent.com/oracle/weblogic-azure/main/weblogic-azure-aks/src/main/resources/mysql-connector-java.xml" +export retryMaxAttempt=5 # retry attempt for curl command + +export wlsAdminURL=$wlsAdminHost:$wlsAdminPort + +validate_input + +install_maven + +if [ $databaseType == "mysql" ]; then + upgrade_mysql_driver +fi + +if [ "${enablePswlessConnection,,}" == "true" ]; then + if [[ $databaseType == "mysql" || $databaseType == "postgresql" ]]; then + install_azure_identity_extension + fi +fi + +uninstall_maven + +if [ $wlsServerName == "admin" ]; then + restart_admin_service +else + restart_managed_servers + echo "Waiting for managed server to start" + sleep 2m +fi diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/postDeploymentScript.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/postDeploymentScript.sh new file mode 100644 index 000000000..cc3790ae2 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/postDeploymentScript.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# Copyright (c) 2021, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +#Function to output message to StdErr +function echo_stderr () +{ + echo "$@" >&2 +} + +#Function to display usage message +function usage() +{ + echo_stderr "./postDeploymentScript.sh " +} + + + +echo "Executing post Deployment script" + +# Get all public ips assigned to the network interface in a given resource group, and follow the below steps +# 1) Get the resource (public IP) tagged with supplied resource tag +# 2) Remove the public IP from netwrok interface +# 3) Finally delete all public IPs + +PUBLIC_IPS="$(az network public-ip list --resource-group ${RESOURCE_GROUP_NAME} --query "[?tags && contains(keys(tags), '${GUID_TAG}')].id" -o tsv)" +if [ -n "${PUBLIC_IPS}" ]; then + echo "Found public IPs to remove: ${PUBLIC_IPS}" + for PUBLIC_IP in ${PUBLIC_IPS}; do + IP_CONFIG_ID=$(az network public-ip show --ids "${PUBLIC_IP}" --query "ipConfiguration.id" -o tsv) + if [ -n "${IP_CONFIG_ID}" ]; then + echo "Found IP configuration: ${IP_CONFIG_ID}" + # Using IP configuration id extract Network interface name and IP config name + NIC_NAME=$(echo "${IP_CONFIG_ID}" | sed 's|.*/networkInterfaces/\([^/]*\)/.*|\1|') + IP_CONFIG_NAME=$(echo "${IP_CONFIG_ID}" | sed 's|.*/ipConfigurations/\([^/]*\).*|\1|') + echo "Removing public IP from NIC: ${NIC_NAME}, IP config: ${IP_CONFIG_NAME}" + az network nic ip-config update -g "${RESOURCE_GROUP_NAME}" --nic-name "${NIC_NAME}" -n "${IP_CONFIG_NAME}" --remove publicIPAddress + fi + done + echo "Deleting public IPs: ${PUBLIC_IPS}" + az network public-ip delete --ids ${PUBLIC_IPS} +else + echo "No public IPs found with tag ${GUID_TAG}" +fi +echo "Deleting $MANAGED_IDENTITY_ID " +az identity delete --ids $MANAGED_IDENTITY_ID \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/setupCoherence.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/setupCoherence.sh index 48ccf5f69..307fcc49c 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/setupCoherence.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/setupCoherence.sh @@ -36,8 +36,8 @@ function validateInput() { echo_stderr "wlsDomainName is required. " fi - if [[ -z "$wlsUserName" || -z "$wlsPassword" ]]; then - echo_stderr "wlsUserName or wlsPassword is required. " + if [[ -z "$wlsUserName" || -z "$wlsShibboleth" ]]; then + echo_stderr "wlsUserName or wlsShibboleth is required. " exit 1 fi @@ -73,30 +73,6 @@ function validateInput() { echo_stderr "enableWebLocalStorage is required. " fi - if [ -z "$enableELK" ]; then - echo_stderr "enableELK is required. " - fi - - if [ -z "$elasticURI" ]; then - echo_stderr "elasticURI is required. " - fi - - if [ -z "$elasticUserName" ]; then - echo_stderr "elasticUserName is required. " - fi - - if [ -z "$elasticPassword" ]; then - echo_stderr "elasticPassword is required. " - fi - - if [ -z "$logsToIntegrate" ]; then - echo_stderr "logsToIntegrate is required. " - fi - - if [ -z "$logIndex" ]; then - echo_stderr "logIndex is required. " - fi - if [ -z "$serverIndex" ]; then echo_stderr "serverIndex is required. " fi @@ -123,6 +99,57 @@ function validateInput() { fi } + +# This function verifies whether certificate is valid and not expired +function verifyCertValidity() +{ + KEYSTORE=$1 + PASSWORD=$2 + CURRENT_DATE=$3 + MIN_CERT_VALIDITY=$4 + KEY_STORE_TYPE=$5 + VALIDITY=$(($CURRENT_DATE + ($MIN_CERT_VALIDITY*24*60*60))) + + echo "Verifying $KEYSTORE is valid at least $MIN_CERT_VALIDITY day from the deployment time" + + if [ $VALIDITY -le $CURRENT_DATE ]; + then + echo "Error : Invalid minimum validity days supplied" + exit 1 + fi + + # Check whether KEYSTORE supplied can be opened for reading + # Redirecting as no need to display the contents + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $KEYSTORE -storepass $PASSWORD -storetype $KEY_STORE_TYPE > /dev/null 2>&1" + if [ $? != 0 ]; + then + echo "Error opening the keystore : $KEYSTORE" + exit 1 + fi + + aliasList=`runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $KEYSTORE -storepass $PASSWORD -storetype $KEY_STORE_TYPE | grep Alias" |awk '{print $3}'` + if [[ -z $aliasList ]]; + then + echo "Error : No alias found in supplied certificate" + exit 1 + fi + + for alias in $aliasList + do + VALIDITY_PERIOD=`runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $KEYSTORE -storepass $PASSWORD -storetype $KEY_STORE_TYPE -alias $alias | grep Valid"` + echo "$KEYSTORE is \"$VALIDITY_PERIOD\"" + CERT_UNTIL_DATE=`echo $VALIDITY_PERIOD | awk -F'until:|\r' '{print $2}'` + CERT_UNTIL_SECONDS=`date -d "$CERT_UNTIL_DATE" +%s` + VALIDITY_REMIANS_SECONDS=`expr $CERT_UNTIL_SECONDS - $VALIDITY` + if [[ $VALIDITY_REMIANS_SECONDS -le 0 ]]; + then + echo "Error : Supplied certificate is either expired or expiring soon within $MIN_CERT_VALIDITY day" + exit 1 + fi + done + echo "$KEYSTORE validation is successful" +} + #run on admin server #create coherence cluster #associate cluster1 with the coherence cluster @@ -130,13 +157,19 @@ function validateInput() { #associate storage1 with the coherence cluster function createCoherenceClusterModel() { cat <$wlsDomainPath/configure-coherence-cluster.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') -shutdown('$clientClusterName', 'Cluster') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') +try: + shutdown('$clientClusterName','Cluster') +except Exception, e: + print e + dumpStack() + try: edit() - startEdit() + startEdit(60000,60000,'true') cd('/') cmo.createCoherenceClusterSystemResource('${coherenceClusterName}') + Thread.sleep(100) cd('/CoherenceClusterSystemResources/${coherenceClusterName}/CoherenceClusterResource/${coherenceClusterName}/CoherenceClusterParams/${coherenceClusterName}') cmo.setClusteringMode('unicast') @@ -144,6 +177,7 @@ try: cd('/') cmo.createCluster('${storageClusterName}') + Thread.sleep(100) cd('/Clusters/${storageClusterName}') cmo.setClusterMessagingMode('unicast') @@ -173,7 +207,9 @@ try: save() activate() -except: +except Exception, e : + print e + dumpStack() stopEdit('y') sys.exit(1) @@ -199,7 +235,7 @@ function create_managed_model() { cat <$wlsDomainPath/managed-domain.yaml domainInfo: AdminUserName: "$wlsUserName" - AdminPassword: "$wlsPassword" + AdminPassword: "$wlsShibboleth" ServerStartMode: prod topology: Name: "$wlsDomainName" @@ -218,6 +254,8 @@ topology: Notes: "$wlsServerName managed server" Cluster: "$storageClusterName" Machine: "$nmHost" + ServerStart: + Arguments: '${SERVER_STARTUP_ARGS}' EOF if [ "${isCustomSSLEnabled}" == "true" ]; @@ -250,7 +288,7 @@ EOF cat <>$wlsDomainPath/managed-domain.yaml SecurityConfiguration: NodeManagerUsername: "$wlsUserName" - NodeManagerPasswordEncrypted: "$wlsPassword" + NodeManagerPasswordEncrypted: "$wlsShibboleth" EOF } @@ -259,11 +297,12 @@ EOF function create_machine_model() { echo "Creating machine name model for managed server $wlsServerName" cat <$wlsDomainPath/add-machine.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') edit("$wlsServerName") -startEdit() +startEdit(60000,60000,'true') cd('/') cmo.createMachine('$nmHost') +Thread.sleep(100) cd('/Machines/$nmHost/NodeManager/$nmHost') cmo.setListenPort(int($nmPort)) cmo.setListenAddress('$nmHost') @@ -282,11 +321,12 @@ function create_ms_server_model() { cat <$wlsDomainPath/add-server.py isCustomSSLEnabled='${isCustomSSLEnabled}' -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') edit("$wlsServerName") -startEdit() +startEdit(60000,60000,'true') cd('/') cmo.createServer('$wlsServerName') +Thread.sleep(100) cd('/Servers/$wlsServerName') cmo.setMachine(getMBean('/Machines/$nmHost')) cmo.setCluster(getMBean('/Clusters/$storageClusterName')) @@ -309,8 +349,13 @@ set('ServerPrivateKeyPassPhrase', '$serverPrivateKeyPassPhrase') cmo.setHostnameVerificationIgnored(true) cd('/Servers/$wlsServerName//ServerStart/$wlsServerName') -arguments = '-Dweblogic.Name=$wlsServerName -Dweblogic.security.SSL.ignoreHostnameVerification=true -Dweblogic.management.server=http://$wlsAdminURL ${wlsCoherenceUnicastPortRange}' -cmo.setArguments(arguments) +arguments = '${SERVER_STARTUP_ARGS} -Dweblogic.Name=$wlsServerName -Dweblogic.management.server=http://$wlsAdminURL ${wlsCoherenceUnicastPortRange}' +oldArgs = cmo.getArguments() +if oldArgs != None: + newArgs = oldArgs + ' ' + arguments +else: + newArgs = arguments +cmo.setArguments(newArgs) save() resolve() activate() @@ -380,9 +425,10 @@ Wants=network-online.target Type=simple # Note that the following three parameters should be changed to the correct paths # on your own system -WorkingDirectory="$wlsDomainPath/$wlsDomainName" -ExecStart="$wlsDomainPath/$wlsDomainName/bin/startNodeManager.sh" -ExecStop="$wlsDomainPath/$wlsDomainName/bin/stopNodeManager.sh" +WorkingDirectory=/u01/domains +Environment="JAVA_OPTIONS=${SERVER_STARTUP_ARGS}" +ExecStart=/bin/bash $wlsDomainPath/$wlsDomainName/bin/startNodeManager.sh +ExecStop=/bin/bash $wlsDomainPath/$wlsDomainName/bin/stopNodeManager.sh User=oracle Group=oracle KillMode=process @@ -399,7 +445,7 @@ EOF function startManagedServer() { echo "Starting managed server $wlsServerName" cat <$wlsDomainPath/start-server.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') try: start('$wlsServerName', 'Server') except: @@ -419,12 +465,14 @@ EOF function createManagedSetup() { echo "Creating Managed Server Setup" cd $wlsDomainPath - wget -q $weblogicDeployTool - if [[ $? != 0 ]]; then - echo "Error : Downloading weblogic-deploy-tool failed" + + # WebLogic base images are already having weblogic-deploy, hence no need to download + if [ ! -d "$wlsDomainPath/weblogic-deploy" ]; + then + echo "weblogic-deploy tool not found in path $wlsDomainPath" exit 1 fi - sudo unzip -o weblogic-deploy.zip -d $wlsDomainPath + echo "Creating managed server model files" create_managed_model create_machine_model @@ -475,9 +523,8 @@ function enabledAndStartNodeManagerService() { function cleanup() { echo "Cleaning up temporary files..." rm -rf $wlsDomainPath/managed-domain.yaml - rm -rf $wlsDomainPath/weblogic-deploy.zip - rm -rf $wlsDomainPath/weblogic-deploy rm -rf $wlsDomainPath/*.py + rm -rf ${CUSTOM_HOSTNAME_VERIFIER_HOME} echo "Cleanup completed." } @@ -520,8 +567,8 @@ function mountFileShare() { fi echo "chmod 600 /etc/smbcredentials/${storageAccountName}.cred" sudo chmod 600 /etc/smbcredentials/${storageAccountName}.cred - echo "//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred ,dir_mode=0777,file_mode=0777,serverino" - sudo bash -c "echo \"//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred ,dir_mode=0777,file_mode=0777,serverino\" >> /etc/fstab" + echo "//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino" + sudo bash -c "echo \"//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino\" >> /etc/fstab" echo "mount -t cifs //${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino" sudo mount -t cifs //${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino if [[ $? != 0 ]]; then @@ -553,6 +600,9 @@ function validateSSLKeyStores() echo "Error : Identity Keystore Validation Failed !!" exit 1 fi + + # Verify Identity keystore validity period more than MIN_CERT_VALIDITY + verifyCertValidity $customIdentityKeyStoreFileName $customIdentityKeyStorePassPhrase $CURRENT_DATE $MIN_CERT_VALIDITY $customIdentityKeyStoreType #validate Trust keystore runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $customTrustKeyStoreFileName -storepass $customTrustKeyStorePassPhrase -storetype $customTrustKeyStoreType | grep 'Entry type:' | grep 'trustedCertEntry'" @@ -562,6 +612,9 @@ function validateSSLKeyStores() exit 1 fi + # Verify Identity keystore validity period more than MIN_CERT_VALIDITY + verifyCertValidity $customTrustKeyStoreFileName $customTrustKeyStorePassPhrase $CURRENT_DATE $MIN_CERT_VALIDITY $customTrustKeyStoreType + echo "ValidateSSLKeyStores Successfull !!" } @@ -578,16 +631,14 @@ function storeCustomSSLCerts() customIdentityKeyStoreData=$(echo "$customIdentityKeyStoreData" | base64 --decode) customIdentityKeyStorePassPhrase=$(echo "$customIdentityKeyStorePassPhrase" | base64 --decode) - customIdentityKeyStoreType=$(echo "$customIdentityKeyStoreType" | base64 --decode) customTrustKeyStoreData=$(echo "$customTrustKeyStoreData" | base64 --decode) customTrustKeyStorePassPhrase=$(echo "$customTrustKeyStorePassPhrase" | base64 --decode) - customTrustKeyStoreType=$(echo "$customTrustKeyStoreType" | base64 --decode) serverPrivateKeyAlias=$(echo "$serverPrivateKeyAlias" | base64 --decode) serverPrivateKeyPassPhrase=$(echo "$serverPrivateKeyPassPhrase" | base64 --decode) - #decode cert data once again as it would got base64 encoded while storing in azure keyvault + #decode cert data once again as it would got base64 encoded while uploading echo "$customIdentityKeyStoreData" | base64 --decode > $customIdentityKeyStoreFileName echo "$customTrustKeyStoreData" | base64 --decode > $customTrustKeyStoreFileName @@ -598,9 +649,75 @@ function storeCustomSSLCerts() fi } +function generateCustomHostNameVerifier() +{ + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME} + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/test/java + cp ${BASE_DIR}/generateCustomHostNameVerifier.sh ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh + cp ${BASE_DIR}/WebLogicCustomHostNameVerifier.java ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java/WebLogicCustomHostNameVerifier.java + cp ${BASE_DIR}/HostNameValuesTemplate.txt ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java/HostNameValuesTemplate.txt + cp ${BASE_DIR}/WebLogicCustomHostNameVerifierTest.java ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/test/java/WebLogicCustomHostNameVerifierTest.java + chown -R $username:$groupname ${CUSTOM_HOSTNAME_VERIFIER_HOME} + chmod +x ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh + + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh ${adminVMName} ${customDNSNameForAdminServer} ${customDNSNameForAdminServer} ${dnsLabelPrefix} ${wlsDomainName} ${location}" +} + +function copyCustomHostNameVerifierJarsToWebLogicClasspath() +{ + runuser -l oracle -c "cp ${CUSTOM_HOSTNAME_VERIFIER_HOME}/output/*.jar $oracleHome/wlserver/server/lib/;" + + echo "Modify WLS CLASSPATH to include hostname verifier jars...." + sed -i 's;^WEBLOGIC_CLASSPATH="${WL_HOME}/server/lib/postgresql.*;&\nWEBLOGIC_CLASSPATH="${WL_HOME}/server/lib/hostnamevalues.jar:${WL_HOME}/server/lib/weblogicustomhostnameverifier.jar:${WEBLOGIC_CLASSPATH}";' $oracleHome/oracle_common/common/bin/commExtEnv.sh + echo "Modified WLS CLASSPATH to include hostname verifier jars." +} + + +function configureCustomHostNameVerifier() +{ + echo "configureCustomHostNameVerifier for domain $wlsDomainName for server $wlsServerName" + cat <$DOMAIN_PATH/configureCustomHostNameVerifier.py +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') +try: + edit("$wlsServerName") + startEdit() + + cd('/Servers/$wlsServerName/SSL/$wlsServerName') + cmo.setHostnameVerifier('com.oracle.azure.weblogic.security.util.WebLogicCustomHostNameVerifier') + cmo.setHostnameVerificationIgnored(false) + cmo.setTwoWaySSLEnabled(false) + cmo.setClientCertificateEnforced(false) + + save() + activate() +except Exception,e: + print e + print "Failed to configureCustomHostNameVerifier for domain $wlsDomainName" + dumpStack() + raise Exception('Failed to configureCustomHostNameVerifier for domain $wlsDomainName') +disconnect() +EOF +sudo chown -R $username:$groupname $DOMAIN_PATH +runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST $DOMAIN_PATH/configureCustomHostNameVerifier.py" +if [[ $? != 0 ]]; then + echo "Error : Failed to configureCustomHostNameVerifier for domain $wlsDomainName" + exit 1 +fi + +} + # main script starts from here SCRIPT_PWD=$(pwd) +CURR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +BASE_DIR="$(readlink -f ${CURR_DIR})" + +# Used for certificate expiry validation +CURRENT_DATE=`date +%s` +# Supplied certificate to have minimum days validity for the deployment +MIN_CERT_VALIDITY="1" + # store arguments in a special array #args=("$@") @@ -613,7 +730,7 @@ SCRIPT_PWD=$(pwd) # echo "ARG[${args[${i}]}]" #done -read wlsDomainName wlsUserName wlsPassword adminVMName oracleHome wlsDomainPath storageAccountName storageAccountKey mountpointPath enableWebLocalStorage enableELK elasticURI elasticUserName elasticPassword logsToIntegrate logIndex managedServerPrefix serverIndex isCustomSSLEnabled customIdentityKeyStoreData customIdentityKeyStorePassPhrase customIdentityKeyStoreType customTrustKeyStoreData customTrustKeyStorePassPhrase customTrustKeyStoreType serverPrivateKeyAlias serverPrivateKeyPassPhrase +read wlsDomainName wlsUserName wlsShibboleth adminVMName oracleHome wlsDomainPath storageAccountName storageAccountKey mountpointPath enableWebLocalStorage managedServerPrefix serverIndex customDNSNameForAdminServer dnsLabelPrefix location isCustomSSLEnabled customIdentityKeyStoreData customIdentityKeyStorePassPhrase customIdentityKeyStoreType customTrustKeyStoreData customTrustKeyStorePassPhrase customTrustKeyStoreType serverPrivateKeyAlias serverPrivateKeyPassPhrase isCustomSSLEnabled="${isCustomSSLEnabled,,}" @@ -627,13 +744,14 @@ nmHost=$(hostname) nmPort=5556 storageClusterName="storage1" storageListenPort=7501 -weblogicDeployTool=https://github.com/oracle/weblogic-deploy-tooling/releases/download/weblogic-deploy-tooling-1.8.1/weblogic-deploy.zip username="oracle" wlsAdminT3ChannelPort=7005 wlsAdminURL="${adminVMName}:${wlsAdminT3ChannelPort}" wlsCoherenceUnicastPortRange="-Dcoherence.localport=$coherenceLocalport -Dcoherence.localport.adjust=$coherenceLocalportAdjust" wlsServerTemplate="myServerTemplate" KEYSTORE_PATH="${wlsDomainPath}/${wlsDomainName}/keystores" +SERVER_STARTUP_ARGS="-Dlog4j2.formatMsgNoLookups=true" +CUSTOM_HOSTNAME_VERIFIER_HOME="/u01/app/custom-hostname-verifier" if [ ${serverIndex} -eq 0 ]; then wlsServerName="admin" @@ -644,6 +762,9 @@ fi validateInput cleanup +# Executing this function first just to make sure certificate errors are first caught +storeCustomSSLCerts + if [ $wlsServerName == "admin" ]; then createCoherenceClusterModel cleanup @@ -651,32 +772,12 @@ else installUtilities mountFileShare openPortsForCoherence - updateNetworkRules - storeCustomSSLCerts createManagedSetup + generateCustomHostNameVerifier + copyCustomHostNameVerifierJarsToWebLogicClasspath createNodeManagerService enabledAndStartNodeManagerService + configureCustomHostNameVerifier startManagedServer cleanup - - echo "enable ELK? ${enableELK}" - chmod ugo+x ${SCRIPT_PWD}/elkIntegrationForConfiguredCluster.sh - if [[ "${enableELK,,}" == "true" ]]; then - echo "Set up ELK..." - ${SCRIPT_PWD}/elkIntegrationForConfiguredCluster.sh \ - ${oracleHome} \ - ${wlsAdminURL} \ - ${wlsUserName} \ - ${wlsPassword} \ - "admin" \ - ${elasticURI} \ - ${elasticUserName} \ - ${elasticPassword} \ - ${wlsDomainName} \ - ${wlsDomainPath}/${wlsDomainName} \ - ${logsToIntegrate} \ - ${serverIndex} \ - ${logIndex} \ - ${managedServerPrefix} - fi fi diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/setupDynamicClusterDomain.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/setupDynamicClusterDomain.sh index 4a659a96c..9622ae909 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/setupDynamicClusterDomain.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/setupDynamicClusterDomain.sh @@ -32,9 +32,9 @@ function validateInput() echo_stderr "wlsDomainName is required. " fi - if [[ -z "$wlsUserName" || -z "$wlsPassword" ]] + if [[ -z "$wlsUserName" || -z "$wlsShibboleth" ]] then - echo_stderr "wlsUserName or wlsPassword is required. " + echo_stderr "wlsUserName or wlsShibboleth is required. " exit 1 fi @@ -109,6 +109,18 @@ function validateInput() exit 1 fi fi + + if [ -z "$virtualNetworkNewOrExisting" ]; + then + echo_stderr "virtualNetworkNewOrExisting is required. " + exit 1 + fi + + if [ -z "$storageAccountPrivateIp" ]; + then + echo_stderr "storageAccountPrivateIp is required. " + exit 1 + fi } #Function to cleanup all temporary files @@ -117,12 +129,63 @@ function cleanup() echo "Cleaning up temporary files..." rm -rf $DOMAIN_PATH/admin-domain.yaml rm -rf $DOMAIN_PATH/managed-domain.yaml - rm -rf $DOMAIN_PATH/deploy-app.yaml - rm -rf $DOMAIN_PATH/shoppingcart.zip rm -rf $DOMAIN_PATH/*.py + rm -rf ${CUSTOM_HOSTNAME_VERIFIER_HOME} echo "Cleanup completed." } +# This function verifies whether certificate is valid and not expired +function verifyCertValidity() +{ + KEYSTORE=$1 + PASSWORD=$2 + CURRENT_DATE=$3 + MIN_CERT_VALIDITY=$4 + KEY_STORE_TYPE=$5 + VALIDITY=$(($CURRENT_DATE + ($MIN_CERT_VALIDITY*24*60*60))) + + echo "Verifying $KEYSTORE is valid at least $MIN_CERT_VALIDITY day from the deployment time" + + if [ $VALIDITY -le $CURRENT_DATE ]; + then + echo "Error : Invalid minimum validity days supplied" + exit 1 + fi + + # Check whether KEYSTORE supplied can be opened for reading + # Redirecting as no need to display the contents + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $KEYSTORE -storepass $PASSWORD -storetype $KEY_STORE_TYPE > /dev/null 2>&1" + if [ $? != 0 ]; + then + echo "Error opening the keystore : $KEYSTORE" + exit 1 + fi + + aliasList=`runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $KEYSTORE -storepass $PASSWORD -storetype $KEY_STORE_TYPE | grep Alias" |awk '{print $3}'` + if [[ -z $aliasList ]]; + then + echo "Error : No alias found in supplied certificate" + exit 1 + fi + + for alias in $aliasList + do + VALIDITY_PERIOD=`runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $KEYSTORE -storepass $PASSWORD -storetype $KEY_STORE_TYPE -alias $alias | grep Valid"` + echo "$KEYSTORE is \"$VALIDITY_PERIOD\"" + CERT_UNTIL_DATE=`echo $VALIDITY_PERIOD | awk -F'until:|\r' '{print $2}'` + CERT_UNTIL_SECONDS=`date -d "$CERT_UNTIL_DATE" +%s` + VALIDITY_REMIANS_SECONDS=`expr $CERT_UNTIL_SECONDS - $VALIDITY` + if [[ $VALIDITY_REMIANS_SECONDS -le 0 ]]; + then + echo_stderr "$KEYSTORE is \"$VALIDITY_PERIOD\"" + echo_stderr "Error : Supplied certificate $KEYSTORE is either expired or expiring soon within $MIN_CERT_VALIDITY day" + exit 1 + fi + done + echo "$KEYSTORE validation is successful" +} + + #Creates weblogic deployment model for admin domain function create_admin_model() { @@ -132,7 +195,7 @@ function create_admin_model() cat <$DOMAIN_PATH/admin-domain.yaml domainInfo: AdminUserName: "$wlsUserName" - AdminPassword: "$wlsPassword" + AdminPassword: "$wlsShibboleth" ServerStartMode: prod topology: Name: "$wlsDomainName" @@ -154,11 +217,11 @@ topology: ListenPort: $wlsAdminT3ChannelPort Protocol: t3 Enabled: true + ServerStart: + Arguments: '${SERVER_STARTUP_ARGS}' SSL: ListenPort: $wlsSSLAdminPort Enabled: true - HostnameVerificationIgnored: true - HostnameVerifier: 'None' EOF if [ "${isCustomSSLEnabled}" == "true" ]; @@ -166,12 +229,6 @@ EOF cat <>$DOMAIN_PATH/admin-domain.yaml ServerPrivateKeyAlias: "$serverPrivateKeyAlias" ServerPrivateKeyPassPhraseEncrypted: "$serverPrivateKeyPassPhrase" -EOF - fi - - if [ "${isCustomSSLEnabled}" == "true" ]; - then -cat <>$DOMAIN_PATH/admin-domain.yaml KeyStores: 'CustomIdentityAndCustomTrust' CustomIdentityKeyStoreFileName: "$customIdentityKeyStoreFileName" CustomIdentityKeyStoreType: "$customIdentityKeyStoreType" @@ -198,22 +255,14 @@ EOF '${dynamicServerTemplate}' : ListenPort: ${wlsManagedPort} Cluster: '${wlsClusterName}' - SSL: - HostnameVerificationIgnored: true - HostnameVerifier: 'None' EOF if [ "${isCustomSSLEnabled}" == "true" ]; then cat <>$DOMAIN_PATH/admin-domain.yaml + SSL: ServerPrivateKeyAlias: "$serverPrivateKeyAlias" ServerPrivateKeyPassPhraseEncrypted: "$serverPrivateKeyPassPhrase" -EOF - fi - - if [ "${isCustomSSLEnabled}" == "true" ]; - then -cat <>$DOMAIN_PATH/admin-domain.yaml KeyStores: 'CustomIdentityAndCustomTrust' CustomIdentityKeyStoreFileName: "$customIdentityKeyStoreFileName" CustomIdentityKeyStoreType: "$customIdentityKeyStoreType" @@ -227,8 +276,21 @@ EOF cat <>$DOMAIN_PATH/admin-domain.yaml SecurityConfiguration: NodeManagerUsername: "$wlsUserName" - NodeManagerPasswordEncrypted: "$wlsPassword" + NodeManagerPasswordEncrypted: "$wlsShibboleth" +EOF + +hasRemoteAnonymousAttribs="$(containsRemoteAnonymousT3RMIIAttribs)" +echo "hasRemoteAnonymousAttribs: ${hasRemoteAnonymousAttribs}" + +if [ "${hasRemoteAnonymousAttribs}" == "true" ]; +then +echo "adding settings to disable remote anonymous t3/rmi disabled under domain security configuration" +cat <>$DOMAIN_PATH/admin-domain.yaml + RemoteAnonymousRmiiiopEnabled: false + RemoteAnonymousRmit3Enabled: false EOF +fi + } #Creates weblogic deployment model for admin domain @@ -238,7 +300,7 @@ function create_managed_model() cat <$DOMAIN_PATH/managed-domain.yaml domainInfo: AdminUserName: "$wlsUserName" - AdminPassword: "$wlsPassword" + AdminPassword: "$wlsShibboleth" ServerStartMode: prod topology: Name: "$wlsDomainName" @@ -263,21 +325,13 @@ topology: '${dynamicServerTemplate}': ListenPort: ${wlsManagedPort} Cluster: '${wlsClusterName}' - SSL: - HostnameVerificationIgnored: true - HostnameVerifier: 'None' EOF if [ "${isCustomSSLEnabled}" == "true" ]; then cat <>$DOMAIN_PATH/managed-domain.yaml + SSL: ServerPrivateKeyAlias: "$serverPrivateKeyAlias" ServerPrivateKeyPassPhraseEncrypted: "$serverPrivateKeyPassPhrase" -EOF - fi - - if [ "${isCustomSSLEnabled}" == "true" ]; - then -cat <>$DOMAIN_PATH/managed-domain.yaml KeyStores: 'CustomIdentityAndCustomTrust' CustomIdentityKeyStoreFileName: "$customIdentityKeyStoreFileName" CustomIdentityKeyStoreType: "$customIdentityKeyStoreType" @@ -291,27 +345,20 @@ EOF cat <>$DOMAIN_PATH/managed-domain.yaml SecurityConfiguration: NodeManagerUsername: "$wlsUserName" - NodeManagerPasswordEncrypted: "$wlsPassword" + NodeManagerPasswordEncrypted: "$wlsShibboleth" EOF -} -# This function to create model for sample application deployment -function create_app_deploy_model() -{ +hasRemoteAnonymousAttribs="$(containsRemoteAnonymousT3RMIIAttribs)" +echo "hasRemoteAnonymousAttribs: ${hasRemoteAnonymousAttribs}" - echo "Creating deploying applicaton model" - cat <$DOMAIN_PATH/deploy-app.yaml -domainInfo: - AdminUserName: "$wlsUserName" - AdminPassword: "$wlsPassword" - ServerStartMode: prod -appDeployments: - Application: - shoppingcart : - SourcePath: "$DOMAIN_PATH/shoppingcart.war" - Target: '${wlsClusterName}' - ModuleType: war +if [ "${hasRemoteAnonymousAttribs}" == "true" ]; +then +echo "adding settings to disable remote anonymous t3/rmi disabled under domain security configuration" +cat <>$DOMAIN_PATH/managed-domain.yaml + RemoteAnonymousRmiiiopEnabled: false + RemoteAnonymousRmit3Enabled: false EOF +fi } #This function create py Script to create Machine on the Domain @@ -323,7 +370,7 @@ function createMachinePyScript() echo "Creating machine name model: $machineName" cat <$DOMAIN_PATH/add-machine.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') try: shutdown('$wlsClusterName','Cluster') @@ -344,12 +391,44 @@ disconnect() EOF } + +#This function sets the server startup arguments to dynamic server template +function createServerStartArgumentPyScript() +{ + +# Exclusive lock is used for startEdit, without that intermittently it is noticed that deployment fails +# Refer issue https://github.com/wls-eng/arm-oraclelinux-wls/issues/280 + + echo "setting server startup arguments for Dynamic Server Template: ${wlsServerTemplate}" + cat <$DOMAIN_PATH/setServerStartArgs.py +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') + +try: + edit() + startEdit(60000,60000,'true') + cd('/ServerTemplates/${wlsServerTemplate}/ServerStart/${wlsServerTemplate}') + arguments = cmo.getArguments() + if(str(arguments) == 'None'): + arguments = '${SERVER_STARTUP_ARGS}' + elif ( '${SERVER_STARTUP_ARGS}' not in str(arguments)): + arguments = str(arguments) + ' ' + '${SERVER_STARTUP_ARGS}' + + cmo.setArguments(arguments) + save() + activate() +except Exception, e: + print e + +disconnect() +EOF +} + #This function creates py Script to enroll Node Manager to the Domain function createEnrollServerPyScript() { echo "Creating managed server $wlsServerName model" cat <$DOMAIN_PATH/enroll-server.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') nmEnroll('$DOMAIN_PATH/$wlsDomainName','$DOMAIN_PATH/$wlsDomainName/nodemanager') nmGenBootStartupProps('$wlsServerName') disconnect() @@ -374,8 +453,6 @@ function create_adminSetup() exit 1 fi - storeCustomSSLCerts - create_admin_model sudo chown -R $username:$groupname $DOMAIN_PATH runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; $DOMAIN_PATH/weblogic-deploy/bin/createDomain.sh -oracle_home $oracleHome -domain_parent $DOMAIN_PATH -domain_type WLS -model_file $DOMAIN_PATH/admin-domain.yaml" @@ -394,7 +471,7 @@ function start_admin() #Create the boot.properties directory mkdir -p "$DOMAIN_PATH/$wlsDomainName/servers/admin/security" echo "username=$wlsUserName" > "$DOMAIN_PATH/$wlsDomainName/servers/admin/security/boot.properties" - echo "password=$wlsPassword" >> "$DOMAIN_PATH/$wlsDomainName/servers/admin/security/boot.properties" + echo "password=$wlsShibboleth" >> "$DOMAIN_PATH/$wlsDomainName/servers/admin/security/boot.properties" sudo chown -R $username:$groupname $DOMAIN_PATH/$wlsDomainName/servers runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; \"$DOMAIN_PATH/$wlsDomainName/startWebLogic.sh\" > "$DOMAIN_PATH/$wlsDomainName/admin.out" 2>&1 &" sleep 3m @@ -408,7 +485,7 @@ function admin_boot_setup() #Create the boot.properties directory mkdir -p "$DOMAIN_PATH/$wlsDomainName/servers/admin/security" echo "username=$wlsUserName" > "$DOMAIN_PATH/$wlsDomainName/servers/admin/security/boot.properties" - echo "password=$wlsPassword" >> "$DOMAIN_PATH/$wlsDomainName/servers/admin/security/boot.properties" + echo "password=$wlsShibboleth" >> "$DOMAIN_PATH/$wlsDomainName/servers/admin/security/boot.properties" sudo chown -R $username:$groupname $DOMAIN_PATH/$wlsDomainName/servers } @@ -444,7 +521,7 @@ function start_cluster() { echo "Starting managed server $wlsServerName" cat <$DOMAIN_PATH/start-cluster.py -connect('$wlsUserName','$wlsPassword','t3://$wlsAdminURL') +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') try: start('$wlsClusterName', 'Cluster') except: @@ -480,10 +557,9 @@ function create_managedSetup(){ exit 1 fi - storeCustomSSLCerts - echo "Creating managed server model files" create_managed_model + createServerStartArgumentPyScript createMachinePyScript createEnrollServerPyScript echo "Completed managed server model files" @@ -509,6 +585,14 @@ function create_managedSetup(){ echo "Error : Adding server $wlsServerName failed" exit 1 fi + + echo "Setting Server Startup Arguments for Dynamic Server Template: ${wlsServerTemplate} " + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST $DOMAIN_PATH/setServerStartArgs.py" + if [[ $? != 0 ]]; then + echo "Error : Adding server startup arguments to Server Template: ${wlsServerTemplate} failed" + exit 1 + fi + } # Create systemctl service for nodemanager @@ -551,9 +635,10 @@ Wants=network-online.target Type=simple # Note that the following three parameters should be changed to the correct paths # on your own system -WorkingDirectory="$DOMAIN_PATH/$wlsDomainName" -ExecStart="$DOMAIN_PATH/$wlsDomainName/bin/startNodeManager.sh" -ExecStop="$DOMAIN_PATH/$wlsDomainName/bin/stopNodeManager.sh" +WorkingDirectory=/u01/domains +Environment="JAVA_OPTIONS=${SERVER_STARTUP_ARGS}" +ExecStart=/bin/bash $DOMAIN_PATH/$wlsDomainName/bin/startNodeManager.sh +ExecStop=/bin/bash $DOMAIN_PATH/$wlsDomainName/bin/stopNodeManager.sh User=oracle Group=oracle KillMode=process @@ -579,9 +664,10 @@ Wants=network-online.target [Service] Type=simple -WorkingDirectory="$DOMAIN_PATH/$wlsDomainName" -ExecStart="${startWebLogicScript}" -ExecStop="${stopWebLogicScript}" +WorkingDirectory=/u01/domains +Environment="JAVA_OPTIONS=${SERVER_STARTUP_ARGS}" +ExecStart=/bin/bash ${startWebLogicScript} +ExecStop=/bin/bash ${stopWebLogicScript} User=oracle Group=oracle KillMode=process @@ -684,13 +770,13 @@ function mountFileShare() fi echo "chmod 600 /etc/smbcredentials/${storageAccountName}.cred" sudo chmod 600 /etc/smbcredentials/${storageAccountName}.cred - echo "//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred ,dir_mode=0777,file_mode=0777,serverino" - sudo bash -c "echo \"//${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred ,dir_mode=0777,file_mode=0777,serverino\" >> /etc/fstab" - echo "mount -t cifs //${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino" - sudo mount -t cifs //${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino + echo "//${storageAccountPrivateIp}/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino" + sudo bash -c "echo \"//${storageAccountPrivateIp}/wlsshare $mountpointPath cifs nofail,vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino\" >> /etc/fstab" + echo "mount -t cifs //${storageAccountPrivateIp}/wlsshare $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino" + sudo mount -t cifs //${storageAccountPrivateIp}/wlsshare $mountpointPath -o vers=2.1,credentials=/etc/smbcredentials/${storageAccountName}.cred,dir_mode=0777,file_mode=0777,serverino if [[ $? != 0 ]]; then - echo "Failed to mount //${storageAccountName}.file.core.windows.net/wlsshare $mountpointPath" + echo "Failed to mount //${storageAccountPrivateIp}/wlsshare $mountpointPath" exit 1 fi } @@ -751,6 +837,9 @@ function validateSSLKeyStores() exit 1 fi + # Verify Identity keystore validity period more than MIN_CERT_VALIDITY + verifyCertValidity $customIdentityKeyStoreFileName $customIdentityKeyStorePassPhrase $CURRENT_DATE $MIN_CERT_VALIDITY $customIdentityKeyStoreType + #validate Trust keystore runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; keytool -list -v -keystore $customTrustKeyStoreFileName -storepass $customTrustKeyStorePassPhrase -storetype $customTrustKeyStoreType | grep 'Entry type:' | grep 'trustedCertEntry'" @@ -758,6 +847,9 @@ function validateSSLKeyStores() echo "Error : Trust Keystore Validation Failed !!" exit 1 fi + + # Verify Identity keystore validity period more than MIN_CERT_VALIDITY + verifyCertValidity $customTrustKeyStoreFileName $customTrustKeyStorePassPhrase $CURRENT_DATE $MIN_CERT_VALIDITY $customTrustKeyStoreType echo "ValidateSSLKeyStores Successfull !!" } @@ -784,7 +876,7 @@ function storeCustomSSLCerts() serverPrivateKeyAlias=$(echo "$serverPrivateKeyAlias" | base64 --decode) serverPrivateKeyPassPhrase=$(echo "$serverPrivateKeyPassPhrase" | base64 --decode) - #decode cert data once again as it would got base64 encoded while storing in azure keyvault + #decode cert data once again as it would got base64 encoded while uploading echo "$customIdentityKeyStoreData" | base64 --decode > $customIdentityKeyStoreFileName echo "$customTrustKeyStoreData" | base64 --decode > $customTrustKeyStoreFileName @@ -795,28 +887,153 @@ function storeCustomSSLCerts() fi } +#this function set the umask 027 (chmod 740) as required by WebLogic security checks +function setUMaskForSecurityDir() +{ + echo "setting umask 027 (chmod 740) for domain/$wlsServerName security directory" + + if [ -f "$DOMAIN_PATH/$wlsDomainName/servers/$wlsServerName/security/boot.properties" ]; + then + runuser -l oracle -c "chmod 740 $DOMAIN_PATH/$wlsDomainName/servers/$wlsServerName/security/boot.properties" + fi + + if [ -d "$DOMAIN_PATH/$wlsDomainName/servers/$wlsServerName/security" ]; + then + runuser -l oracle -c "chmod 740 $DOMAIN_PATH/$wlsDomainName/servers/$wlsServerName/security" + fi + +} + +#this function checks if remote Anonymous T3/RMI Attributes are available as part of domain security configuration +function containsRemoteAnonymousT3RMIIAttribs() +{ + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; $DOMAIN_PATH/weblogic-deploy/bin/modelHelp.sh -oracle_home $oracleHome topology:/SecurityConfiguration | grep RemoteAnonymousRmiiiopEnabled" >> /dev/null + + result1=$? + + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; $DOMAIN_PATH/weblogic-deploy/bin/modelHelp.sh -oracle_home $oracleHome topology:/SecurityConfiguration | grep RemoteAnonymousRmit3Enabled" >> /dev/null + + result2=$? + + if [ $result1 == 0 ] && [ $result2 == 0 ]; then + echo "true" + else + echo "false" + fi +} + + +function generateCustomHostNameVerifier() +{ + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME} + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java + mkdir -p ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/test/java + cp ${BASE_DIR}/generateCustomHostNameVerifier.sh ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh + cp ${BASE_DIR}/WebLogicCustomHostNameVerifier.java ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java/WebLogicCustomHostNameVerifier.java + cp ${BASE_DIR}/HostNameValuesTemplate.txt ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/main/java/HostNameValuesTemplate.txt + cp ${BASE_DIR}/WebLogicCustomHostNameVerifierTest.java ${CUSTOM_HOSTNAME_VERIFIER_HOME}/src/test/java/WebLogicCustomHostNameVerifierTest.java + chown -R $username:$groupname ${CUSTOM_HOSTNAME_VERIFIER_HOME} + chmod +x ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh + + runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; ${CUSTOM_HOSTNAME_VERIFIER_HOME}/generateCustomHostNameVerifier.sh ${adminVMName} ${customDNSNameForAdminServer} ${customDNSNameForAdminServer} ${dnsLabelPrefix} ${wlsDomainName} ${location}" +} + +function copyCustomHostNameVerifierJarsToWebLogicClasspath() +{ + runuser -l oracle -c "cp ${CUSTOM_HOSTNAME_VERIFIER_HOME}/output/*.jar $oracleHome/wlserver/server/lib/;" + + echo "Modify WLS CLASSPATH to include hostname verifier jars...." + sed -i 's;^WEBLOGIC_CLASSPATH="${WL_HOME}/server/lib/postgresql.*;&\nWEBLOGIC_CLASSPATH="${WL_HOME}/server/lib/hostnamevalues.jar:${WL_HOME}/server/lib/weblogicustomhostnameverifier.jar:${WEBLOGIC_CLASSPATH}";' $oracleHome/oracle_common/common/bin/commExtEnv.sh + echo "Modified WLS CLASSPATH to include hostname verifier jars." +} + +function configureCustomHostNameVerifierForAdmin() +{ + echo "configureCustomHostNameVerifier for domain $wlsDomainName for server $wlsServerName" + cat <$DOMAIN_PATH/configureCustomHostNameVerifier.py +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') +try: + edit("$wlsServerName") + startEdit() + + cd('/Servers/$wlsServerName/SSL/$wlsServerName') + cmo.setHostnameVerifier('com.oracle.azure.weblogic.security.util.WebLogicCustomHostNameVerifier') + cmo.setHostnameVerificationIgnored(false) + cmo.setTwoWaySSLEnabled(false) + cmo.setClientCertificateEnforced(false) + + save() + activate() +except Exception,e: + print e + print "Failed to configureCustomHostNameVerifier for domain $wlsDomainName for server $wlsServerName" + dumpStack() + raise Exception('Failed to configureCustomHostNameVerifier for domain $wlsDomainName for server $wlsServerName') +disconnect() +EOF +sudo chown -R $username:$groupname $DOMAIN_PATH +runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST $DOMAIN_PATH/configureCustomHostNameVerifier.py" +if [[ $? != 0 ]]; then + echo "Error : Failed to configureCustomHostNameVerifier for domain $wlsDomainName" + exit 1 +fi + +} + + +function configureCustomHostNameVerifierForServerTemplate() +{ + echo "configureCustomHostNameVerifier for Server Template $dynamicServerTemplate in domain $wlsDomainName" + cat <$DOMAIN_PATH/configureCustomHostNameVerifierServerTemplate.py +connect('$wlsUserName','$wlsShibboleth','t3://$wlsAdminURL') +try: + edit("$dynamicServerTemplate") + startEdit() + + cd('/ServerTemplates/$dynamicServerTemplate/SSL/$dynamicServerTemplate') + cmo.setHostnameVerifier('com.oracle.azure.weblogic.security.util.WebLogicCustomHostNameVerifier') + cmo.setHostnameVerificationIgnored(false) + cmo.setTwoWaySSLEnabled(false) + cmo.setClientCertificateEnforced(false) + + save() + activate() +except Exception,e: + print e + print "Failed to configureCustomHostNameVerifier for Server Template $dynamicServerTemplate in domain $wlsDomainName" + dumpStack() + raise Exception('Failed to configureCustomHostNameVerifier for Server Template $dynamicServerTemplate for domain $wlsDomainName') +disconnect() +EOF +sudo chown -R $username:$groupname $DOMAIN_PATH +runuser -l oracle -c ". $oracleHome/oracle_common/common/bin/setWlstEnv.sh; java $WLST_ARGS weblogic.WLST $DOMAIN_PATH/configureCustomHostNameVerifierServerTemplate.py" +if [[ $? != 0 ]]; then + echo "Error : Failed to configureCustomHostNameVerifier for domain $wlsDomainName" + exit 1 +fi + +} + #main script starts here +SCRIPT_PWD=`pwd` CURR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" BASE_DIR="$(readlink -f ${CURR_DIR})" -# store arguments in a special array -#args=("$@") -# get number of elements -#ELEMENTS=${#args[@]} - -# echo each element in array -# for loop -#for (( i=0;i<$ELEMENTS;i++)); do -# echo "ARG[${args[${i}]}]" -#done +# Used for certificate expiry validation +CURRENT_DATE=`date +%s` +# Supplied certificate to have minimum days validity for the deployment +# In this case set for 1 day +MIN_CERT_VALIDITY="1" -read wlsDomainName wlsUserName wlsPassword managedServerPrefix indexValue vmNamePrefix maxDynamicClusterSize dynamicClusterSize adminVMName oracleHome storageAccountName storageAccountKey mountpointPath isHTTPAdminListenPortEnabled isCustomSSLEnabled customIdentityKeyStoreData customIdentityKeyStorePassPhrase customIdentityKeyStoreType customTrustKeyStoreData customTrustKeyStorePassPhrase customTrustKeyStoreType serverPrivateKeyAlias serverPrivateKeyPassPhrase +read wlsDomainName wlsUserName wlsShibboleth managedServerPrefix indexValue vmNamePrefix maxDynamicClusterSize dynamicClusterSize adminVMName oracleHome storageAccountName storageAccountKey mountpointPath isHTTPAdminListenPortEnabled customDNSNameForAdminServer dnsLabelPrefix location virtualNetworkNewOrExisting storageAccountPrivateIp isCustomSSLEnabled customIdentityKeyStoreData customIdentityKeyStorePassPhrase customIdentityKeyStoreType customTrustKeyStoreData customTrustKeyStorePassPhrase customTrustKeyStoreType serverPrivateKeyAlias serverPrivateKeyPassPhrase DOMAIN_PATH="/u01/domains" +CUSTOM_HOSTNAME_VERIFIER_HOME="/u01/app/custom-hostname-verifier" startWebLogicScript="${DOMAIN_PATH}/${wlsDomainName}/startWebLogic.sh" stopWebLogicScript="${DOMAIN_PATH}/${wlsDomainName}/bin/customStopWebLogic.sh" +SERVER_STARTUP_ARGS="-Dlog4j2.formatMsgNoLookups=true" isHTTPAdminListenPortEnabled="${isHTTPAdminListenPortEnabled,,}" @@ -834,6 +1051,9 @@ wlsManagedPort=8001 wlsAdminURL="$adminVMName:$wlsAdminT3ChannelPort" SERVER_START_URL="http://$wlsAdminURL" KEYSTORE_PATH="${DOMAIN_PATH}/${wlsDomainName}/keystores" +wlsServerTemplate="myServerTemplate" +SERVER_STARTUP_ARGS="-Dlog4j2.formatMsgNoLookups=true" + if [ "${isCustomSSLEnabled}" == "true" ]; then @@ -862,9 +1082,11 @@ else wlsServerName="$managedServerPrefix$serverIndex" fi -SCRIPT_PWD=`pwd` cleanup +# Executing this function first just to make sure certificate errors are first caught +storeCustomSSLCerts + installUtilities mountFileShare @@ -874,16 +1096,26 @@ then create_adminSetup createStopWebLogicScript admin_boot_setup + generateCustomHostNameVerifier + copyCustomHostNameVerifierJarsToWebLogicClasspath + setUMaskForSecurityDir create_adminserver_service create_nodemanager_service enableAndStartAdminServerService enabledAndStartNodeManagerService - wait_for_admin + wait_for_admin + configureCustomHostNameVerifierForAdmin + configureCustomHostNameVerifierForServerTemplate else updateNetworkRules "managed" + wait_for_admin create_managedSetup + generateCustomHostNameVerifier + copyCustomHostNameVerifierJarsToWebLogicClasspath + setUMaskForSecurityDir create_nodemanager_service enabledAndStartNodeManagerService + wait_for_admin start_cluster fi cleanup diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/setupOHS.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/setupOHS.sh index cd47013ae..c100bda75 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/setupOHS.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/setupOHS.sh @@ -51,9 +51,9 @@ function validateInput() exit 1 fi - if [[ -z "$OHS_NM_USER" || -z "$OHS_NM_PSWD" ]] + if [[ -z "$OHS_NM_USER" || -z "$OHS_NM_SHIBBOLETH" ]] then - echo_stderr "OHS nodemanager username and password is required. " + echo_stderr "OHS OHS_NM_USER and OHS_NM_SHIBBOLETH is required. " exit 1 fi @@ -74,14 +74,14 @@ function validateInput() echo_stderr "One of the required values for enabling Custom SSL (ohsKeyStoreData,ohsKeyStorePassPhrase) is not provided" fi - if [ -z "$ORACLE_VAULT_PASSWORD" ] + if [ -z "$ORACLE_VAULT_SHIBBOLETH" ] then - echo_stderr "Oracle vault password is required to add custom ssl to OHS server" + echo_stderr "ORACLE_VAULT_SHIBBOLETH is required to add custom ssl to OHS server" fi - if [ -z "${WLS_USER}" ] || [ -z "${WLS_PASSWORD}" ] + if [ -z "${WLS_USER}" ] || [ -z "${WLS_SHIBBOLETH}" ] then - echo_stderr "Either weblogic username or weblogic password is required" + echo_stderr "Either WLS_USER or WLS_SHIBBOLETH is required" fi if [ -z "$OHS_KEY_TYPE" ] @@ -90,6 +90,57 @@ function validateInput() fi } +# This function verifies whether certificate is valid and not expired +function verifyCertValidity() +{ + KEYSTORE=$1 + PASSWORD=$2 + CURRENT_DATE=$3 + MIN_CERT_VALIDITY=$4 + KEY_STORE_TYPE=$5 + VALIDITY=$(($CURRENT_DATE + ($MIN_CERT_VALIDITY*24*60*60))) + + echo "Verifying $KEYSTORE is valid at least $MIN_CERT_VALIDITY day from the OHS deployment time" + + if [ $VALIDITY -le $CURRENT_DATE ]; + then + echo_stderr "Error : Invalid minimum validity days supplied" + exit 1 + fi + + # Check whether KEYSTORE supplied can be opened for reading + # Redirecting as no need to display the contents + runuser -l oracle -c "$JAVA_HOME/bin/keytool -list -v -keystore $KEYSTORE -storepass $PASSWORD -storetype $KEY_STORE_TYPE > /dev/null 2>&1" + if [ $? != 0 ]; + then + echo_stderr "Error opening the keystore : $KEYSTORE" + exit 1 + fi + + aliasList=`runuser -l oracle -c "$JAVA_HOME/bin/keytool -list -v -keystore $KEYSTORE -storepass $PASSWORD -storetype $KEY_STORE_TYPE | grep Alias" |awk '{print $3}'` + if [[ -z $aliasList ]]; + then + echo_stderr "Error : No alias found in supplied certificate $KEYSTORE" + exit 1 + fi + + for alias in $aliasList + do + VALIDITY_PERIOD=`runuser -l oracle -c "$JAVA_HOME/bin/keytool -list -v -keystore $KEYSTORE -storepass $PASSWORD -storetype $KEY_STORE_TYPE -alias $alias | grep Valid"` + echo "$KEYSTORE is \"$VALIDITY_PERIOD\"" + CERT_UNTIL_DATE=`echo $VALIDITY_PERIOD | awk -F'until:|\r' '{print $2}'` + CERT_UNTIL_SECONDS=`date -d "$CERT_UNTIL_DATE" +%s` + VALIDITY_REMIANS_SECONDS=`expr $CERT_UNTIL_SECONDS - $VALIDITY` + if [[ $VALIDITY_REMIANS_SECONDS -le 0 ]]; + then + echo_stderr "$KEYSTORE is \"$VALIDITY_PERIOD\"" + echo_stderr "Error : Supplied certificate $KEYSTORE is either expired or expiring soon within $MIN_CERT_VALIDITY day" + exit 1 + fi + done + echo "$KEYSTORE validation is successful" +} + # Setup Domain path function setupDomainPath() { @@ -121,7 +172,7 @@ cd('/') create('sc', 'SecurityConfiguration') cd('SecurityConfiguration/sc') set('NodeManagerUsername', "${OHS_NM_USER}") -set('NodeManagerPasswordEncrypted', "${OHS_NM_PSWD}") +set('NodeManagerPasswordEncrypted', "${OHS_NM_SHIBBOLETH}") setOption('NodeManagerType','PerDomainNodeManager') setOption('OverwriteDomain', 'true') writeDomain("${OHS_DOMAIN_PATH}") @@ -183,9 +234,9 @@ function create_nodemanager_service() Wants=network-online.target [Service] Type=simple - WorkingDirectory="$DOMAIN_PATH/$OHS_DOMAIN_NAME" - ExecStart="$DOMAIN_PATH/$OHS_DOMAIN_NAME/bin/startNodeManager.sh" - ExecStop="$DOMAIN_PATH/$OHS_DOMAIN_NAME/bin/stopNodeManager.sh" + WorkingDirectory=/u01/domains + ExecStart=/bin/bash $DOMAIN_PATH/$OHS_DOMAIN_NAME/bin/startNodeManager.sh + ExecStop=/bin/bash $DOMAIN_PATH/$OHS_DOMAIN_NAME/bin/stopNodeManager.sh User=oracle Group=oracle KillMode=process @@ -225,7 +276,7 @@ function createStartComponent() { cat < $OHS_DOMAIN_PATH/startComponent.py import os, sys -nmConnect(username='${OHS_NM_USER}',password='${OHS_NM_PSWD}',domainName='${OHS_DOMAIN_NAME}') +nmConnect(username='${OHS_NM_USER}',password='${OHS_NM_SHIBBOLETH}',domainName='${OHS_DOMAIN_NAME}') status=nmServerStatus(serverName='${OHS_COMPONENT_NAME}',serverType='OHS') if status != "RUNNING": nmStart(serverName='${OHS_COMPONENT_NAME}',serverType='OHS') @@ -242,7 +293,7 @@ function createStopComponent() { cat < $OHS_DOMAIN_PATH/stopComponent.py import os, sys -nmConnect(username='${OHS_NM_USER}',password='${OHS_NM_PSWD}',domainName='${OHS_DOMAIN_NAME}') +nmConnect(username='${OHS_NM_USER}',password='${OHS_NM_SHIBBOLETH}',domainName='${OHS_DOMAIN_NAME}') status=nmServerStatus(serverName='${OHS_COMPONENT_NAME}',serverType='OHS') if status != "SHUTDOWN": nmKill(serverName='$OHS_COMPONENT_NAME',serverType='OHS') @@ -308,7 +359,7 @@ function enableAndStartOHSServerService() # Query the WLS and form WLS cluster address function getWLSClusterAddress() { - restArgs=" -v --user ${WLS_USER}:${WLS_PASSWORD} -H X-Requested-By:MyClient -H Accept:application/json -H Content-Type:application/json" + restArgs=" -v --user ${WLS_USER}:${WLS_SHIBBOLETH} -H X-Requested-By:MyClient -H Accept:application/json -H Content-Type:application/json" curl $restArgs -X GET ${WLS_REST_URL}/domainRuntime/serverRuntimes?fields=defaultURL > out if [[ $? != 0 ]]; then @@ -391,7 +442,7 @@ function updateNetworkRules() function createOracleVault() { runuser -l oracle -c "mkdir -p ${OHS_VAULT_PATH}" - runuser -l oracle -c "${INSTALL_PATH}/oracle/middleware/oracle_home/oracle_common/bin/orapki wallet create -wallet ${OHS_VAULT_PATH} -pwd ${ORACLE_VAULT_PASSWORD} -auto_login" + runuser -l oracle -c "${INSTALL_PATH}/oracle/middleware/oracle_home/oracle_common/bin/orapki wallet create -wallet ${OHS_VAULT_PATH} -pwd ${ORACLE_VAULT_SHIBBOLETH} -auto_login" if [[ $? == 0 ]]; then echo "Successfully oracle vault is created" @@ -413,9 +464,11 @@ function addCertficateToOracleVault() echo "$ohsKeyStoreData" | base64 --decode > ${OHS_VAULT_PATH}/ohsKeystore.jks sudo chown -R $username:$groupname ${OHS_VAULT_PATH}/ohsKeystore.jks # Validate JKS file - KEY_TYPE=`keytool -list -v -keystore ${OHS_VAULT_PATH}/ohsKeystore.jks -storepass ${ohsKeyStorePassPhrase} | grep 'Keystore type:'` + verifyCertValidity ${OHS_VAULT_PATH}/ohsKeystore.jks $ohsKeyStorePassPhrase $CURRENT_DATE $MIN_CERT_VALIDITY "JKS" + + KEY_TYPE=`$JAVA_HOME/bin/keytool -list -v -keystore ${OHS_VAULT_PATH}/ohsKeystore.jks -storepass ${ohsKeyStorePassPhrase} | grep 'Keystore type:'` if [[ $KEY_TYPE == *"jks"* ]]; then - runuser -l oracle -c "${INSTALL_PATH}/oracle/middleware/oracle_home/oracle_common/bin/orapki wallet jks_to_pkcs12 -wallet ${OHS_VAULT_PATH} -pwd ${ORACLE_VAULT_PASSWORD} -keystore ${OHS_VAULT_PATH}/ohsKeystore.jks -jkspwd ${ohsKeyStorePassPhrase}" + runuser -l oracle -c "${INSTALL_PATH}/oracle/middleware/oracle_home/oracle_common/bin/orapki wallet jks_to_pkcs12 -wallet ${OHS_VAULT_PATH} -pwd ${ORACLE_VAULT_SHIBBOLETH} -keystore ${OHS_VAULT_PATH}/ohsKeystore.jks -jkspwd ${ohsKeyStorePassPhrase}" if [[ $? == 0 ]]; then echo "Successfully added JKS keystore to Oracle Wallet" else @@ -431,7 +484,10 @@ function addCertficateToOracleVault() "PKCS12") echo "$ohsKeyStoreData" | base64 --decode > ${OHS_VAULT_PATH}/ohsCert.p12 sudo chown -R $username:$groupname ${OHS_VAULT_PATH}/ohsCert.p12 - runuser -l oracle -c "${INSTALL_PATH}/oracle/middleware/oracle_home/oracle_common/bin/orapki wallet import_pkcs12 -wallet ${OHS_VAULT_PATH} -pwd ${ORACLE_VAULT_PASSWORD} -pkcs12file ${OHS_VAULT_PATH}/ohsCert.p12 -pkcs12pwd ${ohsKeyStorePassPhrase}" + # Validate PKCS12 file + verifyCertValidity ${OHS_VAULT_PATH}/ohsCert.p12 $ohsKeyStorePassPhrase $CURRENT_DATE $MIN_CERT_VALIDITY "PKCS12" + + runuser -l oracle -c "${INSTALL_PATH}/oracle/middleware/oracle_home/oracle_common/bin/orapki wallet import_pkcs12 -wallet ${OHS_VAULT_PATH} -pwd ${ORACLE_VAULT_SHIBBOLETH} -pkcs12file ${OHS_VAULT_PATH}/ohsCert.p12 -pkcs12pwd ${ohsKeyStorePassPhrase}" if [[ $? == 0 ]]; then echo "Successfully added certificate to Oracle Wallet" else @@ -472,10 +528,16 @@ function verifyService() CURR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" BASE_DIR="$(readlink -f ${CURR_DIR})" -read OHS_DOMAIN_NAME OHS_COMPONENT_NAME OHS_NM_USER OHS_NM_PSWD OHS_HTTP_PORT OHS_HTTPS_PORT WLS_REST_URL WLS_USER WLS_PASSWORD OHS_KEY_STORE_DATA OHS_KEY_STORE_PASSPHRASE ORACLE_VAULT_PASSWORD OHS_KEY_TYPE +# Used for certificate expiry validation +CURRENT_DATE=`date +%s` +# Supplied certificate to have minimum days validity for the deployment +# In this case set for 1 day +MIN_CERT_VALIDITY="1" + +read OHS_DOMAIN_NAME OHS_COMPONENT_NAME OHS_NM_USER OHS_NM_SHIBBOLETH OHS_HTTP_PORT OHS_HTTPS_PORT WLS_REST_URL WLS_USER WLS_SHIBBOLETH OHS_KEY_STORE_DATA OHS_KEY_STORE_PASSPHRASE ORACLE_VAULT_SHIBBOLETH OHS_KEY_TYPE JDK_PATH="/u01/app/jdk" -JDK_VERSION="jdk1.8.0_271" +JDK_VERSION="jdk1.8.0_291" JAVA_HOME=$JDK_PATH/$JDK_VERSION PATH=$JAVA_HOME/bin:$PATH OHS_PATH="/u01/app/ohs" diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/updateDNSZones.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/updateDNSZones.sh index a7d15407f..78f21e8a2 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/updateDNSZones.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/scripts/updateDNSZones.sh @@ -1,40 +1,44 @@ #!/bin/bash # Copyright (c) 2021, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# - -resourceGroup=$1 -zoneName=$2 -recordSetNames=$3 -targetResources=$4 -lenRecordset=$5 -lenTargets=$6 -ttl=${7} -cnameRecordSetNames=${8} -cnameAlias=${9} -lenCnameRecordSetNames=${10} -lenCnameAlias=${11} - -if [[ ${lenRecordset} != ${lenTargets} ]]; then + +# Description +# This script updates the Azure DNS Zones used for configuring DNS for WebLogic Admin Server and Azure Application Gateway. + +# Inputs: +# RESOURCE_GROUP_NAME +# DNS_ZONE_NAME +# DNS_RECORDSET_NAMES +# DNS_TARGET_RESOURCES +# DNS_RECORD_NAMES_LENGTH +# DNS_TARGET_RESOURCES_LENGTH +# DNS_RECORD_TTL +# DNS_CNAME_RECORDSET_NAMES +# DNS_CNAME_ALIAS +# DNS_CNAME_RECORDSET_LENGTH +# DNS_CNAME_ALIAS_LENGTH +# MANAGED_IDENTITY_ID + +if [[ ${DNS_RECORD_NAMES_LENGTH} != ${DNS_TARGET_RESOURCES_LENGTH} ]]; then echo "Error: number of A record set names is not equal to that of target resources." exit 1 fi -if [[ ${lenCnameRecordSetNames} != ${lenCnameAlias} ]]; then +if [[ ${DNS_CNAME_RECORDSET_LENGTH} != ${DNS_CNAME_ALIAS_LENGTH} ]]; then echo "Error: number of CNAME record set names is not equal to that of alias." exit 1 fi # check if the zone exist -az network dns zone show -g ${resourceGroup} -n ${zoneName} +az network dns zone show -g ${RESOURCE_GROUP_NAME} -n ${DNS_ZONE_NAME} # query name server for testing -nsforTest=$(az network dns record-set ns show -g ${resourceGroup} -z ${zoneName} -n @ --query "nsRecords"[0].nsdname -o tsv) +nsforTest=$(az network dns record-set ns show -g ${RESOURCE_GROUP_NAME} -z ${DNS_ZONE_NAME} -n @ --query "nsRecords"[0].nsdname -o tsv) echo name server: ${nsforTest} -if [ ${lenRecordset} -gt 0 ]; then - recordSetNamesArr=$(echo $recordSetNames | tr "," "\n") - targetResourcesArr=$(echo $targetResources | tr "," "\n") +if [ ${DNS_RECORD_NAMES_LENGTH} -gt 0 ]; then + recordSetNamesArr=$(echo $DNS_RECORDSET_NAMES | tr "," "\n") + targetResourcesArr=$(echo $DNS_TARGET_RESOURCES | tr "," "\n") index=0 for record in $recordSetNamesArr; do @@ -43,13 +47,13 @@ if [ ${lenRecordset} -gt 0 ]; then if [ $count -eq $index ]; then echo Create A record with name: $record, target IP: $target az network dns record-set a create \ - -g ${resourceGroup} \ - -z ${zoneName} \ + -g ${RESOURCE_GROUP_NAME} \ + -z ${DNS_ZONE_NAME} \ -n ${record} \ --target-resource ${target} \ - --ttl ${ttl} + --ttl ${DNS_RECORD_TTL} - nslookup ${record}.${zoneName} ${nsforTest} + nslookup ${record}.${DNS_ZONE_NAME} ${nsforTest} if [ $? -eq 1 ];then echo Error: failed to create record with name: $record, target Id: $target exit 1 @@ -63,9 +67,9 @@ if [ ${lenRecordset} -gt 0 ]; then done fi -if [ ${lenCnameRecordSetNames} -gt 0 ];then - cnameRecordSetArr=$(echo $cnameRecordSetNames | tr "," "\n") - cnameRecordAliasArr=$(echo $cnameAlias | tr "," "\n") +if [ ${DNS_CNAME_RECORDSET_LENGTH} -gt 0 ];then + cnameRecordSetArr=$(echo $DNS_CNAME_RECORDSET_NAMES | tr "," "\n") + cnameRecordAliasArr=$(echo $DNS_CNAME_ALIAS | tr "," "\n") index=0 for record in $cnameRecordSetArr; do @@ -74,18 +78,18 @@ if [ ${lenCnameRecordSetNames} -gt 0 ];then if [ $count -eq $index ]; then echo Create CNAME record with name: $record, alias: $target az network dns record-set cname create \ - -g ${resourceGroup} \ - -z ${zoneName} \ + -g ${RESOURCE_GROUP_NAME} \ + -z ${DNS_ZONE_NAME} \ -n ${record} \ - --ttl ${ttl} + --ttl ${DNS_RECORD_TTL} az network dns record-set cname set-record \ - -g ${resourceGroup} \ - -z ${zoneName} \ + -g ${RESOURCE_GROUP_NAME} \ + -z ${DNS_ZONE_NAME} \ --cname ${target} \ --record-set-name ${record} - nslookup ${record}.${zoneName} ${nsforTest} + nslookup ${record}.${DNS_ZONE_NAME} ${nsforTest} if [ $? -eq 1 ];then echo Error: failed to create CNAME record with name: $record, alia: $target exit 1 @@ -98,3 +102,7 @@ if [ ${lenCnameRecordSetNames} -gt 0 ];then index=$((index + 1)) done fi + +# delete user assigned managed identity + +az identity delete --ids ${MANAGED_IDENTITY_ID} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/cli-scripts/custom-dns-alias-cli.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/cli-scripts/custom-dns-alias-cli.sh index 199cded75..79e8c2564 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/cli-scripts/custom-dns-alias-cli.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/cli-scripts/custom-dns-alias-cli.sh @@ -24,7 +24,6 @@ Options: -z --zone-name (Required) DNS Zone name --ohs-vm-name (Optional) Specify name of the VM that hosts the Oracle HTTP Server Load Balancer. --loadbalancer-label (Optional) Specify a lable to generate the DNS alias for Load Balancer - --identity-id (Optional) Specify an Azure Managed User Identity to update DNS Zone --zone-resource-group (Optional) The name of resource group that has WebLogic cluster deployed -h --help @@ -39,7 +38,6 @@ Samples: --zone-name contoso.com \\ --ohs-vm-name ohsVM \\ --loadbalancer-label application \\ - --identity-id \\ --zone-resource-group haiche-dns-test1 2. Configure DNS alias on a new DNS Zone @@ -212,14 +210,6 @@ EOF "hasDNSZones": { "value": ${hasDNSZone} }, - "identity": { - "value": { - "type": "UserAssigned", - "userAssignedIdentities": { - "${identity}": {} - } - } - }, "location": { "value": "${location}" }, @@ -294,7 +284,6 @@ Custom DNS alias: # default value enableLB=false hasDNSZone=false -identity=/subscriptions/subscriptionId/resourceGroups/TestResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/TestUserIdentity1 # Transform long options to short ones for arg in "$@"; do @@ -308,7 +297,6 @@ for arg in "$@"; do "--admin-console-label") set -- "$@" "-c" ;; "--loadbalancer-label") set -- "$@" "-w" ;; "--zone-resource-group") set -- "$@" "-r" ;; - "--identity-id") set -- "$@" "-i" ;; "--location") set -- "$@" "-l" ;; "--ohs-vm-name") set -- "$@" "-o" ;; "--"*) @@ -334,7 +322,6 @@ while getopts "hg:f:z:m:c:w:r:i:l:o:" opt; do "c") adminLabel="$OPTARG" ;; "w") lbLabel="$OPTARG" ;; "r") zoneResourceGroup="$OPTARG" ;; - "i") identity="$OPTARG" ;; "l") location="$OPTARG" ;; "o") ohsVMName="$OPTARG" ;; esac diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/deletenode/pom.xml b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/deletenode/pom.xml index bed47ec88..bf6795168 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/deletenode/pom.xml +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/deletenode/pom.xml @@ -1,36 +1,39 @@ - + 4.0.0 - com.oracle.weblogic.azure - arm-oraclelinux-wls-dynamic-cluster-deletenode - 1.0.0 - - com.microsoft.azure.iaas - azure-javaee-iaas-parent - 1.0.7 - + com.oracle.weblogic.azure + weblogic-azure-vm + 1.0.0 + ../../pom.xml - + + com.oracle.weblogic.azure + arm-oraclelinux-wls-dynamic-cluster-deletenode + ${version.arm-oraclelinux-wls-dynamic-cluster-deletenode} + jar ${project.artifactId} - ${basedir}/../../arm-ttk/arm-ttk - -TestParameter '@{"SampleName"="deletenode/src/main";"RawRepoPath"="${artifactsLocationBase}/arm-oraclelinux-wls-dynamic-cluster/${git.tag}/"}' - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/pid.properties - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/microsoft-pid.properties + -TestParameter '@{"SampleName"="deletenode/src/main";"RawRepoPath"="${artifactsLocationBase}/arm-oraclelinux-wls-dynamic-cluster/"}' + ${project.basedir}/../../.. + false + false - + diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/deletenode/src/main/arm/mainTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/deletenode/src/main/arm/mainTemplate.json index 77e59bb2a..4677f1b92 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/deletenode/src/main/arm/mainTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/deletenode/src/main/arm/mainTemplate.json @@ -7,7 +7,7 @@ "metadata": { "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." }, - "defaultValue": "${artifactsLocationBase}/arm-oraclelinux-wls-dynamic-cluster/${git.tag}/deletenode/src/main/" + "defaultValue": "${artifactsLocationBase}/arm-oraclelinux-wls-dynamic-cluster/deletenode/src/main/" }, "_artifactsLocationSasToken": { "type": "securestring", @@ -77,7 +77,6 @@ "variables": { "const_wlsAdminPort": "7001", "const_wlsHome": "/u01/app/wls/install/oracle/middleware/oracle_home", - "const_outputCliCommands": "[concat('export resourceGroup=', resourceGroup().name,';', 'export deleteingIDs=\"\";export managedServerMachineNames=$(echo ',array.join(parameters('deletingManagedServerMachineNames')),' | tr \",\" \"\\n\");','az extension add --name resource-graph;','for machine in $managedServerMachineNames;do vmId=$(az graph query -q \"Resources | where type =~ ','\\','\"microsoft.compute/virtualmachines\\\" | where name=~ \\\"${machine}\\\" | where resourceGroup =~ \\\"${resourceGroup}\\\" | project vmid = id\" -o tsv); nicId=$(az graph query -q \"Resources | where type =~ \\\"microsoft.compute/virtualmachines\\\" | where name=~ \\\"${machine}\\\" | where resourceGroup =~ \\\"${resourceGroup}\\\" | extend nics=array_length(properties.networkProfile.networkInterfaces) | mv-expand nic=properties.networkProfile.networkInterfaces | where nics == 1 or nic.properties.primary =~ \\\"true\\\" or isempty(nic) | project nicId = tostring(nic.id)\" -o tsv);ipId=$(az graph query -q \"Resources | where type =~ \\\"microsoft.network/networkinterfaces\\\" | where id=~ \\\"${nicId}\\\" | extend ipConfigsCount=array_length(properties.ipConfigurations) | mv-expand ipconfig=properties.ipConfigurations | where ipConfigsCount == 1 or ipconfig.properties.primary =~ \\\"true\\\" | project publicIpId = tostring(ipconfig.properties.publicIPAddress.id)\" -o tsv);osDiskId=$(az graph query -q \"Resources | where type =~ \\\"microsoft.compute/virtualmachines\\\" | where name=~ \\\"${machine}\\\" | where resourceGroup =~ \\\"${resourceGroup}\\\" | project osDiskId = tostring(properties.storageProfile.osDisk.managedDisk.id)\" -o tsv);dataDiskIds=$(az graph query -q \"Resources | where type =~ \\\"microsoft.compute/virtualmachines\\\" | where name=~ \\\"${machine}\\\" | where resourceGroup =~ \\\"${resourceGroup}\\\" | mv-expand datadisk=properties.storageProfile.dataDisks | project datadisk.managedDisk.id\" -o tsv);deleteingIDs=$(echo $deleteingIDs ${vmId} ${nicId} ${ipId} ${osDiskId} ${dataDiskIds});done;echo \"List resource Ids to be deleted: \";echo ${deleteingIDs} | tr \" \" \"\\n\";echo -n \"Are you sure to delete these resources (y/n)?\";read answer;if [[ \"$answer\" != \"${answer#[Yy]}\" && -n \"${deleteingIDs}\" ]]; then echo \"Deleting managed resources...Please do not stop.\";az resource delete --verbose --ids ${deleteingIDs};fi')]", "name_scriptDeleteNode": "deletenode.sh" }, "functions": [ @@ -102,7 +101,7 @@ "resources": [ { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${dynamic.deletenode.start}", "properties": { "mode": "Incremental", @@ -115,8 +114,8 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "${azure.apiVersion}", "name": "[concat(parameters('adminVMName'),'/newuserscript')]", "location": "[parameters('location')]", "properties": { @@ -136,7 +135,7 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${dynamic.deletenode.end}", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('adminVMName'), 'newuserscript')]" @@ -155,7 +154,7 @@ "outputs": { "commandsToDeleteAzureResource": { "type": "string", - "value": "[variables('const_outputCliCommands')]" + "value": "[concat('export resourceGroup=', resourceGroup().name,';', 'export deleteingIDs=\"\";export managedServerMachineNames=$(echo ',array.join(parameters('deletingManagedServerMachineNames')),' | tr \",\" \"\\n\");','az extension add --name resource-graph;','for machine in $managedServerMachineNames;do vmId=$(az graph query -q \"Resources | where type =~ ','\\','\"microsoft.compute/virtualmachines\\\" | where name=~ \\\"${machine}\\\" | where resourceGroup =~ \\\"${resourceGroup}\\\" | project vmid = tolower(id)\" --query data[0].vmid -o tsv); nicId=$(az graph query -q \"Resources | where type =~ \\\"microsoft.compute/virtualmachines\\\" | where name=~ \\\"${machine}\\\" | where resourceGroup =~ \\\"${resourceGroup}\\\" | extend nics=array_length(properties.networkProfile.networkInterfaces) | mv-expand nic=properties.networkProfile.networkInterfaces | where nics == 1 or nic.properties.primary =~ \\\"true\\\" or isempty(nic) | project nicId = tostring(nic.id)\" --query data[0].nicId -o tsv);ipId=$(az graph query -q \"Resources | where type =~ \\\"microsoft.network/networkinterfaces\\\" | where id=~ \\\"${nicId}\\\" | extend ipConfigsCount=array_length(properties.ipConfigurations) | mv-expand ipconfig=properties.ipConfigurations | where ipConfigsCount == 1 or ipconfig.properties.primary =~ \\\"true\\\" | project publicIpId = tostring(ipconfig.properties.publicIPAddress.id)\" --query data[0].publicIpId -o tsv);osDiskId=$(az graph query -q \"Resources | where type =~ \\\"microsoft.compute/virtualmachines\\\" | where name=~ \\\"${machine}\\\" | where resourceGroup =~ \\\"${resourceGroup}\\\" | project osDiskId = tostring(properties.storageProfile.osDisk.managedDisk.id)\" --query data[0].osDiskId -o tsv);deleteingIDs=$(echo $deleteingIDs ${vmId} ${nicId} ${ipId} ${osDiskId});done;echo \"List resource Ids to be deleted: \";echo ${deleteingIDs} | tr \" \" \"\\n\";echo -n \"Are you sure to delete these resources (y/n)?\";read answer;if [[ \"$answer\" != \"${answer#[Yy]}\" && -n \"${deleteingIDs}\" ]]; then echo \"Deleting managed resources...Please do not stop.\";az resource delete --verbose --ids ${deleteingIDs};fi')]" } } } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/pom.xml b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/pom.xml index fdc5f72ee..7cd131f0e 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/pom.xml +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/pom.xml @@ -8,23 +8,30 @@ 4.0.0 + + com.oracle.weblogic.azure + weblogic-azure-vm + 1.0.0 + ../pom.xml + + com.oracle.weblogic.azure arm-oraclelinux-wls-dynamic-cluster-root pom - 1.0.8 + 1.0.9 ${project.artifactId} - + - https://github.com/wls-eng/arm-oraclelinux-wls-dynamic-cluster + https://github.com/oracle/weblogic-azure/tree/main/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster scm:git:git@github.com:wls-eng/arm-oraclelinux-wls-dynamic-cluster.git scm:git:git@github.com:wls-eng/arm-oraclelinux-wls-dynamic-cluster.git - https://github.com/wls-eng/arm-oraclelinux-wls-dynamic-cluster + https://github.com/oracle/weblogic-azure/tree/main/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster HEAD - + Universal Permissive License Version 1.0 @@ -33,6 +40,10 @@ + + ${project.parent.basedir}/.. + + addnode addnode-coherence diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/src/main/resources/marketing-artifacts/partner-center.html b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/src/main/resources/marketing-artifacts/partner-center.html new file mode 100644 index 000000000..2d1fd438a --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/src/main/resources/marketing-artifacts/partner-center.html @@ -0,0 +1,51 @@ +

    Name

    +

    Oracle WebLogic Server Dynamic Cluster on Azure VMs

    +

    Search results summary

    +

    Provisions an n-node Oracle WebLogic Server dynamic cluster on Azure VMs.

    +

    Short description

    +

    Provisions an n-node Oracle WebLogic Server Enterprise Edition dynamic cluster on Azure VMs. Supports integration with +Oracle HTTP Server, databases, and Coherence.

    +

    Description

    +

    Oracle WebLogic Server (WLS) is an industry-leading Java runtime powering some of the most mission-critical enterprise applications + across the globe. This solution automates most boilerplate steps to provision a WLS dynamic cluster on Azure VMs. Once initial + provisioning is complete, you are completely free to customize deployments further. The solution is jointly developed by Oracle and + Microsoft.

    +

    WLS Enterprise Edition versions supported include 12.2.1.4, and 14.1.1.0.

    +

    The following resources are automatically provisioned by the offer.

    +
      +
    • Oracle Linux or Red Hat Enterprise Linux (RHEL) VMs (you can choose the number of VMs - all instances will have private +IP addresses by default)
    • +
    • Dynamic cluster consisting of WebLogic Managed Server instances on each VM (ORACLE_HOME is +/u01/app/wls/install/oracle/middleware/oracle_home)
    • +
    • Admin Server on one of the VMs
    • +
    • WLS Domain with default name wlsd (domain path is /u01/domains/wlsd/)
    • +
    • Oracle JDK on each VM (JAVA_HOME is /u01/app/jdk/jdk-${version})
    • +
    • Oracle HTTP Server (OHS) VM instance with a public IP address by default for load balancing (ORACLE_HOME +is /u01/app/ohs/install/oracle/middleware/oracle_home) - optional
    • +
    • In addition to drivers that come standard with WLS, most recent supported PostgreSQL and Microsoft SQL JDBC drivers (drivers stored in +/u01/app/wls/install/oracle/middleware/oracle_home/wlserver/server/lib/)
    • +
    • Configured data source connection (Oracle DB, Azure SQL, Azure MySQL, Azure PostgreSQL) - optional
    • +
    • VMs with private IP addresses to run data tier Managed Coherence cache servers - optional
    • +
    • Virtual network and subnet (alternatively, you can deploy to an existing virtual network)
    • +
    • Network security group
    • +
    • OS disks attached to VMs
    • +
    • Storage Account, to store VM diagnostics, and file share named +wlsshare (mount point is /mnt/wlsshare)
    • +
    +

    This offer is Bring-Your-Own-License. It assumes you have already procured the appropriate licenses with Oracle and are properly +licensed to run offers in Microsoft Azure.

    +

    Oracle and Microsoft also provide basic step-by-step instructions on getting started with WLS and Azure VMs without automated +provisioning.

    +

    Oracle and Microsoft provide similar solutions targeting WLS on the Azure Kubernetes Service (AKS) in addition to a single WLS +Admin Server instance on an Azure VM. These options are linked in the Learn more section below.

    +

    You can reach out to the engineering team developing these offers by clicking the CONTACT ME button on +the marketplace WebLogic on Azure overview page. Program managers, architects and engineers will get in touch and can +assist you for free with your Azure migration.

    +

    Links

    + diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/deploy-webapp.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/deploy-webapp.sh new file mode 100644 index 000000000..0088bcfc5 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/deploy-webapp.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +# Copyright (c) 2021, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +# Description +# This script is to test application deployment on WebLogic cluster domain. + +# Verifying admin server is accessible + +read wlsUserName wlspassword adminVMDNS adminPort + +CURL_REQD_PARMS="--user ${wlsUserName}:${wlspassword} -H X-Requested-By:MyClient -H Accept:application/json -s -v" +CURL_RETRY_PARMS="--connect-timeout 60 --max-time 180 --retry 10 --retry-delay 30 --retry-max-time 180 --retry-connrefused" + +echo "curl ${CURL_REQD_PARMS} ${CURL_RETRY_PARMS} -H Content-Type:multipart/form-data \ +-H "weblogic.edit.session: default" \ +-F \"model={ + name: 'weblogic-cafe', + targets: [ { identity: [ 'clusters', 'cluster1' ] } ] +}\" \ +-F \"sourcePath=@weblogic-on-azure/javaee/weblogic-cafe/target/weblogic-cafe.war\" \ +-X Prefer:respond-async \ +-X POST http://${adminVMDNS}:${adminPort}/management/weblogic/latest/edit/appDeployments" + +# Deploy webapp to weblogic server +curl ${CURL_REQD_PARMS} ${CURL_RETRY_PARMS} -H Content-Type:multipart/form-data \ +-H "weblogic.edit.session: default" \ +-F "model={ + name: 'weblogic-cafe', + targets: [ { identity: [ 'clusters', 'cluster1' ] } ] +}" \ +-F "sourcePath=@weblogic-on-azure/javaee/weblogic-cafe/target/weblogic-cafe.war" \ +-H "Prefer:respond-async" \ +-X POST http://${adminVMDNS}:${adminPort}/management/weblogic/latest/edit/appDeployments > out + +echo "Deployment response received" +cat out + +attempt=0 +while [ $attempt -le 10 ] +do + curl ${CURL_REQD_PARMS} ${CURL_RETRY_PARMS} \ + -X GET -i "http://${adminVMDNS}:${adminPort}/management/weblogic/latest/domainRuntime/deploymentManager/deploymentProgressObjects/weblogic-cafe?links=none" > out + echo "Checking deployment operation is completed" + cat out | grep "\"state\": \"STATE_COMPLETED\"" + if [ $? == 0 ]; then + echo "Deployment operation is completed" + cat out + break + fi + attempt=$((attempt+1)) + sleep 10s +done + +echo "Verifying the deployed application status" +sleep 1m + +attempt=0 +while [ $attempt -le 5 ] +do + echo "curl ${CURL_REQD_PARMS} ${CURL_RETRY_PARMS} -H weblogic.edit.session: default -H Content-Type:application/json -d {target='cluster1'} -X POST -i http://${adminVMDNS}:${adminPort}/management/weblogic/latest/domainRuntime/deploymentManager/appDeploymentRuntimes/weblogic-cafe/getState" + curl ${CURL_REQD_PARMS} ${CURL_RETRY_PARMS} -H Content-Type:application/json \ + -H "weblogic.edit.session: default" \ + -d "{target='cluster1'}" \ + -X POST -i "http://${adminVMDNS}:${adminPort}/management/weblogic/latest/domainRuntime/deploymentManager/appDeploymentRuntimes/weblogic-cafe/getState" > out + + echo "Deployment state received" + cat out + cat out | grep "\"return\": \"STATE_ACTIVE\"" + if [ $? == 0 ]; then + echo "Application is deployed successfully and in active state" + exit 0 + elif [[ $? != 0 ]] && [[ $attempt -ge 5 ]]; then + echo "Application deployment is unsuccessful" + exit 1 + fi + + cat out | grep "\"return\": \"STATE_PREPARED\"" + if [[ $? == 0 ]]; then + # Ideally this is not required but noticed only for 122130 OL7.4 it is required + echo "Starting the service explicitly" + echo "curl ${CURL_REQD_PARMS} ${CURL_RETRY_PARMS} -H weblogic.edit.session: default -H Content-Type:application/json -d {} -X POST -i http://${adminVMDNS}:${adminPort}/management/weblogic/latest/domainRuntime/deploymentManager/appDeploymentRuntimes/weblogic-cafe/start" + curl ${CURL_REQD_PARMS} ${CURL_RETRY_PARMS} -H Content-Type:application/json \ + -H "weblogic.edit.session: default" \ + -d "{}" \ + -X POST -i "http://${adminVMDNS}:${adminPort}/management/weblogic/latest/domainRuntime/deploymentManager/appDeploymentRuntimes/weblogic-cafe/start" + fi + + attempt=$((attempt+1)) + sleep 1m +done diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-aad-ag.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-aad-ag.sh deleted file mode 100644 index d86171b37..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-aad-ag.sh +++ /dev/null @@ -1,87 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# - -read parametersPath githubUserName testbranchName keyVaultName keyVaultResourceGroup keyVaultSSLCertDataSecretName keyVaultSSLCertPasswordSecretName - -cat < ${parametersPath} -{ - "\$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "_artifactsLocation": { - "value": "https://raw.githubusercontent.com/${githubUserName}/arm-oraclelinux-wls-dynamic-cluster/${testbranchName}/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/" - }, - "_artifactsLocationSasToken": { - "value": "" - }, - "aadsPortNumber": { - "value": "636" - }, - "aadsPublicIP": { - "value": "GEN-UNIQUE" - }, - "aadsServerHost": { - "value": "GEN-UNIQUE" - }, - "adminPasswordOrKey": { - "value": "GEN-UNIQUE" - }, - "adminUsername": { - "value": "GEN-UNIQUE" - }, - "enableAAD": { - "value": true - }, - "enableDB": { - "value": false - }, - "keyVaultName": { - "value": "${keyVaultName}" - }, - "keyVaultResourceGroup": { - "value": "${keyVaultResourceGroup}" - }, - "keyVaultSSLCertDataSecretName": { - "value": "${keyVaultSSLCertDataSecretName}" - }, - "keyVaultSSLCertPasswordSecretName": { - "value": "${keyVaultSSLCertPasswordSecretName}" - }, - "maxDynamicClusterSize": { - "value": 4 - }, - "dynamicClusterSize": { - "value": 2 - }, - "vmSizeSelect": { - "value": "Standard_D2as_v4" - }, - "wlsLDAPGroupBaseDN": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPPrincipal": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPPrincipalPassword": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPProviderName": { - "value": "AzureActiveDirectoryProvider" - }, - "wlsLDAPSSLCertificate": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPUserBaseDN": { - "value": "GEN-UNIQUE" - }, - "wlsPassword": { - "value": "GEN-UNIQUE" - }, - "wlsUserName": { - "value": "GEN-UNIQUE" - } - } -} -EOF diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-aad.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-aad.sh deleted file mode 100644 index 9460c8b6f..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-aad.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# - -read parametersPath githubUserName testbranchName - -cat < ${parametersPath} -{ - "\$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "_artifactsLocation": { - "value": "https://raw.githubusercontent.com/${githubUserName}/arm-oraclelinux-wls-dynamic-cluster/${testbranchName}/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/" - }, - "_artifactsLocationSasToken": { - "value": "" - }, - "aadsPortNumber": { - "value": "636" - }, - "aadsPublicIP": { - "value": "GEN-UNIQUE" - }, - "aadsServerHost": { - "value": "GEN-UNIQUE" - }, - "adminPasswordOrKey": { - "value": "GEN-UNIQUE" - }, - "adminUsername": { - "value": "GEN-UNIQUE" - }, - "enableAAD": { - "value": true - }, - "enableDB": { - "value": false - }, - "maxDynamicClusterSize": { - "value": 4 - }, - "dynamicClusterSize": { - "value": 2 - }, - "vmSizeSelect": { - "value": "Standard_D2as_v4" - }, - "wlsLDAPGroupBaseDN": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPPrincipal": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPPrincipalPassword": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPProviderName": { - "value": "AzureActiveDirectoryProvider" - }, - "wlsLDAPSSLCertificate": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPUserBaseDN": { - "value": "GEN-UNIQUE" - }, - "wlsPassword": { - "value": "GEN-UNIQUE" - }, - "wlsUserName": { - "value": "GEN-UNIQUE" - } - } -} -EOF diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-coherence.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-coherence.sh index 7a5ccd8b5..47bab649e 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-coherence.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-coherence.sh @@ -3,15 +3,15 @@ # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. # -read parametersPath githubUserName testbranchName +read parametersPath repoPath testbranchName cat <${parametersPath} { - "\$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "\$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "_artifactsLocation": { - "value": "https://raw.githubusercontent.com/${githubUserName}/arm-oraclelinux-wls-dynamic-cluster/${testbranchName}/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/" + "value": "https://raw.githubusercontent.com/${repoPath}/${testbranchName}/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/" }, "_artifactsLocationSasToken": { "value": "" @@ -28,8 +28,8 @@ cat <${parametersPath} "enableCoherence": { "value": true }, - "vmSizeSelect": { - "value": "Standard_D2as_v4" + "vmSize": { + "value": "Standard_B2ms" }, "wlsPassword": { "value": "GEN-UNIQUE" diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-db-aad.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-db-aad.sh deleted file mode 100644 index e221a85f6..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-db-aad.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# - -read parametersPath githubUserName testbranchName - -cat < ${parametersPath} -{ - "\$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "_artifactsLocation": { - "value": "https://raw.githubusercontent.com/${githubUserName}/arm-oraclelinux-wls-dynamic-cluster/${testbranchName}/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/" - }, - "_artifactsLocationSasToken": { - "value": "" - }, - "aadsPortNumber": { - "value": "636" - }, - "aadsPublicIP": { - "value": "GEN-UNIQUE" - }, - "aadsServerHost": { - "value": "GEN-UNIQUE" - }, - "adminPasswordOrKey": { - "value": "GEN-UNIQUE" - }, - "adminUsername": { - "value": "GEN-UNIQUE" - }, - "databaseType": { - "value": "postgresql" - }, - "dbPassword": { - "value": "GEN-UNIQUE" - }, - "dbUser": { - "value": "GEN-UNIQUE" - }, - "dsConnectionURL": { - "value": "GEN-UNIQUE" - }, - "enableAAD": { - "value": true - }, - "enableDB": { - "value": true - }, - "jdbcDataSourceName": { - "value": "jdbc/postgresql" - }, - "maxDynamicClusterSize": { - "value": 4 - }, - "dynamicClusterSize": { - "value": 2 - }, - "vmSizeSelect": { - "value": "Standard_D2as_v4" - }, - "wlsLDAPGroupBaseDN": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPPrincipal": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPPrincipalPassword": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPProviderName": { - "value": "AzureActiveDirectoryProvider" - }, - "wlsLDAPSSLCertificate": { - "value": "GEN-UNIQUE" - }, - "wlsLDAPUserBaseDN": { - "value": "GEN-UNIQUE" - }, - "wlsPassword": { - "value": "GEN-UNIQUE" - }, - "wlsUserName": { - "value": "GEN-UNIQUE" - } - } -} -EOF diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-db.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-db.sh index 00a9c2246..50cfb8327 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-db.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-db.sh @@ -3,15 +3,15 @@ # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. # -read parametersPath githubUserName testbranchName +read parametersPath repoPath testbranchName cat < ${parametersPath} { - "\$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "\$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "_artifactsLocation": { - "value": "https://raw.githubusercontent.com/${githubUserName}/arm-oraclelinux-wls-dynamic-cluster/${testbranchName}/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/" + "value": "https://raw.githubusercontent.com/${repoPath}/${testbranchName}/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/" }, "_artifactsLocationSasToken": { "value": "" @@ -34,9 +34,6 @@ cat < ${parametersPath} "dsConnectionURL": { "value": "GEN-UNIQUE" }, - "enableAAD": { - "value": false - }, "enableDB": { "value": true }, @@ -49,8 +46,8 @@ cat < ${parametersPath} "dynamicClusterSize": { "value": 2 }, - "vmSizeSelect": { - "value": "Standard_D2as_v4" + "vmSize": { + "value": "Standard_B2ms" }, "wlsPassword": { "value": "GEN-UNIQUE" diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-addnode-coherence.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-addnode-coherence.sh deleted file mode 100644 index d33c6d560..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-addnode-coherence.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# -#Generate parameters with value for deploying addnode template - -read parametersPath adminPasswordOrKey adminVMName adminUsername numberOfExistingCacheNodes skuUrnVersion storageAccountName wlsDomainName location wlsusername wlspassword gitUserName testbranchName managedServerPrefix - -cat < ${parametersPath} -{ - "adminPasswordOrKey":{ - "value": "${adminPasswordOrKey}" - }, - "adminVMName": { - "value": "${adminVMName}" - }, - "adminUsername": { - "value": "${adminUsername}" - }, - "numberOfExistingCacheNodes": { - "value": ${numberOfExistingCacheNodes} - }, - "numberOfNewCacheNodes": { - "value": 1 - }, - "location": { - "value": "${location}" - }, - "skuUrnVersion": { - "value": "${skuUrnVersion}" - }, - "storageAccountName": { - "value": "${storageAccountName}" - }, - "vmSizeSelectForCoherence": { - "value": "Standard_D2as_v4" - }, - "wlsDomainName": { - "value": "${wlsDomainName}" - }, - "wlsPassword": { - "value": "${wlsPassword}" - }, - "wlsUserName": { - "value": "${wlsUserName}" - }, - "_artifactsLocation":{ - "value": "https://raw.githubusercontent.com/${gitUserName}/arm-oraclelinux-wls-dynamic-cluster/${testbranchName}/addnode-coherence/src/main/" - }, - "managedServerPrefix": { - "value": "${managedServerPrefix}" - } - } -EOF diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-addnode.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-addnode.sh deleted file mode 100644 index 33aac06b2..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-addnode.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# -#Generate parameters with value for deploying addnode template - -read parametersPath adminPasswordOrKey adminURL adminUsername numberOfExistingNodes skuUrnVersion storageAccountName wlsDomainName location wlsusername wlspassword gitUserName testbranchName managedServerPrefix dynamicClusterSize maxDynamicClusterSize - -cat < ${parametersPath} -{ - "adminPasswordOrKey":{ - "value": "${adminPasswordOrKey}" - }, - "adminURL": { - "value": "${adminURL}" - }, - "adminUsername": { - "value": "${adminUsername}" - }, - "numberOfExistingNodes": { - "value": ${numberOfExistingNodes} - }, - "numberOfNewNodes": { - "value": 1 - }, - "location": { - "value": "${location}" - }, - "skuUrnVersion": { - "value": "${skuUrnVersion}" - }, - "storageAccountName": { - "value": "${storageAccountName}" - }, - "vmSizeSelect": { - "value": "Standard_D2as_v4" - }, - "wlsDomainName": { - "value": "${wlsDomainName}" - }, - "wlsPassword": { - "value": "${wlsPassword}" - }, - "wlsUserName": { - "value": "${wlsUserName}" - }, - "_artifactsLocation":{ - "value": "https://raw.githubusercontent.com/${gitUserName}/arm-oraclelinux-wls-dynamic-cluster/${testbranchName}/addnode/src/main/" - }, - "managedServerPrefix": { - "value": "${managedServerPrefix}" - }, - "dynamicClusterSize": { - "value": ${dynamicClusterSize} - }, - "maxDynamicClusterSize": { - "value": ${maxDynamicClusterSize} - } -} -EOF diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-coherence.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-coherence.sh index 69234a45c..210fd1bc9 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-coherence.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-coherence.sh @@ -4,7 +4,7 @@ # #Generate parameters with value for deploying coherence template independently -read parametersPath adminVMName adminPasswordOrKey skuUrnVersion location storageAccountName wlsDomainName wlsusername wlspassword gitUserName testbranchName managedServerPrefix +read parametersPath adminVMName adminPasswordOrKey skuUrnVersion location storageAccountName wlsDomainName wlsusername wlspassword repoPath testbranchName managedServerPrefix cat < ${parametersPath} { @@ -30,7 +30,7 @@ cat < ${parametersPath} "value": "${storageAccountName}" }, "vmSizeSelectForCoherence": { - "value": "Standard_D2as_v4" + "value": "Standard_B2ms" }, "wlsDomainName": { "value": "${wlsDomainName}" @@ -42,7 +42,7 @@ cat < ${parametersPath} "value": "${wlsUserName}" }, "_artifactsLocation":{ - "value": "https://raw.githubusercontent.com/${gitUserName}/arm-oraclelinux-wls-dynamic-cluster/${testbranchName}/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/" + "value": "https://raw.githubusercontent.com/${repoPath}/${testbranchName}/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/" }, "managedServerPrefix": { "value": "${managedServerPrefix}" diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-db.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-db.sh index f9f865935..48f0234ba 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-db.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-db.sh @@ -4,7 +4,7 @@ # #Generate parameters with value for deploying db template independently -read parametersPath adminVMName dbPassword dbName location wlsusername wlspassword gitUserName testbranchName +read parametersPath adminVMName dbPassword dbAdminUser dbName location wlsusername wlspassword repoPath testbranchName cat < ${parametersPath}/parameters-deploy-db.json { @@ -18,7 +18,7 @@ cat < ${parametersPath}/parameters-deploy-db.json "value": "${dbPassword}" }, "dbUser": { - "value": "weblogic@${dbName}" + "value": "${dbAdminUser}" }, "dsConnectionURL": { "value": "jdbc:postgresql://${dbName}.postgres.database.azure.com:5432/postgres?sslmode=require" @@ -36,7 +36,7 @@ cat < ${parametersPath}/parameters-deploy-db.json "value": "${wlsUserName}" }, "_artifactsLocation":{ - "value": "https://raw.githubusercontent.com/${gitUserName}/arm-oraclelinux-wls-dynamic-cluster/${testbranchName}/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/" + "value": "https://raw.githubusercontent.com/${repoPath}/${testbranchName}/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/" }, } EOF diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-deletenode.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-deletenode.sh deleted file mode 100644 index 42fad97f8..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-deletenode.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# -#Generate parameters with value for deploying delete-node template - -read parametersPath adminVMName location wlsusername wlspassword gitUserName testbranchName managedServerPrefix - -cat < ${parametersPath} - { - "adminVMName":{ - "value": "${adminVMName}" - }, - "deletingManagedServerMachineNames": { - "value": ["${managedServerPrefix}VM2"] - }, - "location": { - "value": "${location}" - }, - "wlsPassword": { - "value": "${wlsPassword}" - }, - "wlsUserName": { - "value": "${wlsUserName}" - }, - "_artifactsLocation":{ - "value": "https://raw.githubusercontent.com/${gitUserName}/arm-oraclelinux-wls-dynamic-cluster/${testbranchName}/deletenode/src/main/" - } - } -EOF diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-elk.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-elk.sh deleted file mode 100644 index 63435730f..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy-elk.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# -#Generate parameters with value for deploying elk template independently - -read parametersPath adminVMName elasticsearchPassword elasticsearchURI elasticsearchUserName location wlsDomainName wlsusername wlspassword gitUserName testbranchName managedServerPrefix maxDynamicClusterSize dynamicClusterSize guidValue - - -cat < ${parametersPath} -{ - "adminVMName":{ - "value": "${adminVMName}" - }, - "elasticsearchPassword": { - "value": "${elasticsearchPassword}" - }, - "elasticsearchEndpoint": { - "value": "${elasticsearchURI}" - }, - "elasticsearchUserName": { - "value": "${elasticsearchUserName}" - }, - "guidValue": { - "value": "${guidValue}" - }, - "location": { - "value": "${location}" - }, - "wlsDomainName": { - "value": "${wlsDomainName}" - }, - "wlsPassword": { - "value": "${wlsPassword}" - }, - "wlsUserName": { - "value": "${wlsUserName}" - }, - "_artifactsLocation":{ - "value": "https://raw.githubusercontent.com/${gitUserName}/arm-oraclelinux-wls-dynamic-cluster/${testbranchName}/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/" - }, - "managedServerPrefix": { - "value": "${managedServerPrefix}" - }, - "maxDynamicClusterSize": { - "value": ${maxDynamicClusterSize} - }, - "numberOfManagedApplicationInstances": { - "value": ${dynamicClusterSize} - }, - "guidValue": { - "value": "${guidValue}" - } - } -EOF diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy.sh index 21842aceb..d2165ee9d 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-deploy.sh @@ -3,12 +3,12 @@ # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. # #Generate parameters with value for deployment -read parametersPath location adminPasswordOrKey wlsdomainname wlsusername wlspassword managedserverprefix maxDynamicClusterSize dynamicClusterSize adminvmname skuUrnVersion testbranchName gitUserName +read parametersPath location adminPasswordOrKey wlsdomainname wlsusername wlspassword managedserverprefix maxDynamicClusterSize dynamicClusterSize skuUrnVersion testbranchName repoPath dbName dbServerName dbPassword dbUser uploadedKeyStoreData cat <${parametersPath} { - "\$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "\$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "adminUsername": { @@ -38,11 +38,8 @@ cat <${parametersPath} "dynamicClusterSize": { "value": $dynamicClusterSize }, - "adminVMName": { - "value": "$adminvmname" - }, - "vmSizeSelect": { - "value": "Standard_D2as_v4" + "vmSize": { + "value": "Standard_B2ms" }, "location": { "value": "$location" @@ -52,7 +49,63 @@ cat <${parametersPath} }, "_artifactsLocation": { - "value": "https://raw.githubusercontent.com/${gitUserName}/arm-oraclelinux-wls-dynamic-cluster/${testbranchName}/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/" + "value": "https://raw.githubusercontent.com/${repoPath}/${testbranchName}/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/" + }, + "addressPrefixes": { + "value": [ + "172.16.8.0/28" + ] + }, + "subnetPrefix": { + "value": "172.16.8.0/28" + }, + "enableCoherence": { + "value": true + }, + "enableCoherenceWebLocalStorage": { + "value": true + }, + "enableDB": { + "value": true + }, + "databaseType": { + "value": "postgresql" + }, + "dsConnectionURL": { + "value": "jdbc:postgresql://${dbServerName}.postgres.database.azure.com:5432/${dbName}?sslmode=require" + }, + "dbGlobalTranPro": { + "value": "EmulateTwoPhaseCommit" + }, + "dbPassword": { + "value": "${dbPassword}" + }, + "dbUser": { + "value": "${dbUser}" + }, + "jdbcDataSourceName": { + "value": "jdbc/WebLogicCafeDB" + }, + "enableOHS": { + "value": true + }, + "ohsNMUser": { + "value": "weblogic" + }, + "ohsNMPassword": { + "value": "$wlspassword" + }, + "oracleVaultPswd": { + "value": "$wlspassword" + }, + "uploadedKeyStoreData": { + "value": "${uploadedKeyStoreData}" + }, + "uploadedKeyStorePassword": { + "value": "$wlspassword" + }, + "uploadedKeyStoreType": { + "value": "JKS" } } } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-elk.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-elk.sh deleted file mode 100644 index 228d52673..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters-elk.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# - -read parametersPath githubUserName testbranchName - -cat <${parametersPath} -{ - "\$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "_artifactsLocation": { - "value": "https://raw.githubusercontent.com/${githubUserName}/arm-oraclelinux-wls-dynamic-cluster/${testbranchName}/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/" - }, - "_artifactsLocationSasToken": { - "value": "" - }, - "adminPasswordOrKey": { - "value": "GEN-UNIQUE" - }, - "adminUsername": { - "value": "GEN-UNIQUE" - }, - "elasticsearchPassword": { - "value": "GEN-UNIQUE" - }, - "elasticsearchEndpoint": { - "value": "GEN-UNIQUE" - }, - "elasticsearchUserName": { - "value": "GEN-UNIQUE" - }, - "enableAAD": { - "value": false - }, - "enableDB": { - "value": false - }, - "enableELK": { - "value": true - }, - "vmSizeSelect": { - "value": "Standard_D2as_v4" - }, - "wlsPassword": { - "value": "GEN-UNIQUE" - }, - "wlsUserName": { - "value": "GEN-UNIQUE" - } - } -} -EOF diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters.sh index d72b0ca56..b00ebc13a 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/gen-parameters.sh @@ -3,15 +3,15 @@ # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. # -read parametersPath githubUserName testbranchName +read parametersPath repoPath testbranchName -cat < ${parametersPath} +cat <${parametersPath} { - "\$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "\$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "_artifactsLocation": { - "value": "https://raw.githubusercontent.com/${githubUserName}/arm-oraclelinux-wls-dynamic-cluster/${testbranchName}/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/" + "value": "https://raw.githubusercontent.com/${repoPath}/${testbranchName}/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/" }, "_artifactsLocationSasToken": { "value": "" @@ -22,9 +22,6 @@ cat < ${parametersPath} "adminUsername": { "value": "GEN-UNIQUE" }, - "enableAAD": { - "value": false - }, "enableDB": { "value": false }, @@ -34,8 +31,8 @@ cat < ${parametersPath} "dynamicClusterSize": { "value": 2 }, - "vmSizeSelect": { - "value": "Standard_D2as_v4" + "vmSize": { + "value": "Standard_B2ms" }, "wlsPassword": { "value": "GEN-UNIQUE" @@ -46,4 +43,3 @@ cat < ${parametersPath} } } EOF - diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/generate-selfsigned-keystore.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/generate-selfsigned-keystore.sh new file mode 100644 index 000000000..698648a05 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/generate-selfsigned-keystore.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +# After running this script, you will have the following files in the current directory: +# identity.jks - Identity keystore +# trust.jks - Trust keystore +# root.cert - Root certificate + +read wlsDemoIdentityKeyStorePassPhrase wlsDemoIdentityPassPhrase wlsDemoTrustPassPhrase + +export wlsIdentityKeyStoreFileName="identity.jks" +export wlsTrustKeyStoreFileName="trust.jks" +export wlsIdentityRootCertFileName="root.cert" +export wlsDemoIndetityKeyAlias="demoidentity" + +function generate_selfsigned_certificates() { + # Note: JDK 8 keytool will create jks by default + # JDK 11 keytool will create PKCS12 by default + # This file uses JDK 11 and generates JKS. + echo "Generate identity key store." + ${JAVA_HOME}/bin/keytool -genkey \ + -alias ${wlsDemoIndetityKeyAlias} \ + -keyalg RSA -keysize 2048 \ + -sigalg SHA256withRSA -validity 365 \ + -keystore $wlsIdentityKeyStoreFileName \ + -keypass ${wlsDemoIdentityPassPhrase} \ + -storepass ${wlsDemoIdentityKeyStorePassPhrase} \ + -storetype JKS \ + -dname "CN=*.cloudapp.azure.com, OU=test, O=test, L=test, ST=test, C=test" + + # update the input variables with Demo values + echo "Exporting root cert from identity key store" + ${JAVA_HOME}/bin/keytool -export \ + -alias ${wlsDemoIndetityKeyAlias} \ + -noprompt \ + -file ${wlsIdentityRootCertFileName} \ + -keystore $wlsIdentityKeyStoreFileName \ + -storepass ${wlsDemoIdentityKeyStorePassPhrase} + + echo "Generate trust key store." + ${JAVA_HOME}/bin/keytool -import \ + -alias ${wlsDemoIndetityKeyAlias} \ + -noprompt \ + -file ${wlsIdentityRootCertFileName} \ + -keystore ${wlsTrustKeyStoreFileName} \ + -storepass ${wlsDemoTrustPassPhrase} \ + -storetype JKS +} + +# check if the self-signed certificates already exist +if [ -f "$wlsIdentityKeyStoreFileName" ] && [ -f "$wlsTrustKeyStoreFileName" ] && [ -f "$wlsIdentityRootCertFileName" ]; then + echo "Self-signed certificates already exist. Skipping generation." + exit 0 +else + echo "Self-signed certificates do not exist. Generating new ones." +fi + +echo "Starting to generate selfsigned certificates" +generate_selfsigned_certificates \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/parameters-deploy-template.json b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/parameters-deploy-template.json new file mode 100644 index 000000000..f838c43c1 --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/parameters-deploy-template.json @@ -0,0 +1,103 @@ +{ + "adminUsername": { + "value": "weblogic" + }, + "adminPasswordOrKey": { + "value": "$adminPasswordOrKey" + }, + "dnsLabelPrefix": { + "value": "wls" + }, + "wlsDomainName": { + "value": "$wlsdomainname" + }, + "wlsUserName": { + "value": "$wlsusername" + }, + "wlsPassword": { + "value": "$wlspassword" + }, + "managedServerPrefix": { + "value": "$managedServerPrefix" + }, + "maxDynamicClusterSize": { + "value": $maxDynamicClusterSize + }, + "dynamicClusterSize": { + "value": $dynamicClusterSize + }, + "vmSize": { + "value": "Standard_B2ms" + }, + "location": { + "value": "$location" + }, + "skuUrnVersion": { + "value": "$skuUrnVersion" + }, + "_artifactsLocation": { + "value": "https://raw.githubusercontent.com/${repoPath}/${testbranchName}/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/arm-oraclelinux-wls-dynamic-cluster/src/main/arm/" + }, + "addressPrefixes": { + "value": [ + "172.16.8.0/28" + ] + }, + "subnetPrefix": { + "value": "172.16.8.0/28" + }, + "enableCoherence": { + "value": true + }, + "enableCoherenceWebLocalStorage": { + "value": true + }, + "enableDB": { + "value": ${enableDB} + }, + "databaseType": { + "value": "${databaseType}" + }, + "dsConnectionURL": { + "value": "${dsConnectionURL}" + }, + "dbGlobalTranPro": { + "value": "EmulateTwoPhaseCommit" + }, + "dbPassword": { + "value": "${dbPassword}" + }, + "dbUser": { + "value": "${dbUser}" + }, + "jdbcDataSourceName": { + "value": "jdbc/WebLogicCafeDB" + }, + "enableOHS": { + "value": true + }, + "ohsNMUser": { + "value": "weblogic" + }, + "ohsNMPassword": { + "value": "$wlspassword" + }, + "oracleVaultPswd": { + "value": "$wlspassword" + }, + "uploadedKeyStoreData": { + "value": "${uploadedKeyStoreData}" + }, + "uploadedKeyStorePassword": { + "value": "$wlspassword" + }, + "uploadedKeyStoreType": { + "value": "JKS" + }, + "enablePswlessConnection": { + "value": ${enablePswlessConnection} + }, + "dbIdentity": { + "value": ${dbIdentity} + } +} diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-admin-services.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-admin-services.sh new file mode 100644 index 000000000..3b54c7bcf --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-admin-services.sh @@ -0,0 +1,43 @@ +#!/bin/bash +# Copyright (c) 2021, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +# Verify the service using systemctl status +function verifyServiceStatus() +{ + serviceName=$1 + systemctl status $serviceName | grep "active (running)" + if [[ $? != 0 ]]; then + echo "$serviceName is not in active (running) state" + exit 1 + fi + echo "$serviceName is active (running)" +} + +#Verify the service using systemctl is-active +function verifyServiceActive() +{ + serviceName=$1 + state=$(systemctl is-active $serviceName) + if [[ $state == "active" ]]; then + echo "$serviceName is active" + else + echo "$serviceName is not active" + exit 1 + fi +} + +# Pass the services to be checked based on admin/managed servers +# For admin server : rngd wls_admin wls_nodemanager +# For managed server : rngd wls_nodemanager + +servicesList="rngd wls_admin wls_nodemanager" + +for service in $servicesList +do + verifyServiceStatus $service + verifyServiceActive $service +done + +exit 0 + diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-deployments.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-deployments.sh index 860ca7668..0600ba65c 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-deployments.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-deployments.sh @@ -3,7 +3,7 @@ # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. # -read prefix location template githubUserName testbranchName scriptsDir +read prefix location template repoPath testbranchName scriptsDir groupName=${prefix}-preflight @@ -13,29 +13,13 @@ az group create --verbose --name $groupName --location ${location} # generate parameters for testing differnt cases parametersList=() # parameters for cluster -bash ${scriptsDir}/gen-parameters.sh <<< "${scriptsDir}/parameters.json $githubUserName $testbranchName" +bash ${scriptsDir}/gen-parameters.sh <<< "${scriptsDir}/parameters.json $repoPath $testbranchName" parametersList+=(${scriptsDir}/parameters.json) # parameters for cluster+db -bash ${scriptsDir}/gen-parameters-db.sh <<< "${scriptsDir}/parameters-db.json $githubUserName $testbranchName" +bash ${scriptsDir}/gen-parameters-db.sh <<< "${scriptsDir}/parameters-db.json $repoPath $testbranchName" parametersList+=(${scriptsDir}/parameters-db.json) -# parameters for cluster+aad -bash ${scriptsDir}/gen-parameters-aad.sh <<< "${scriptsDir}/parameters-aad.json $githubUserName $testbranchName" -parametersList+=(${scriptsDir}/parameters-aad.json) - -# parameters for cluster+coherence -bash ${scriptsDir}/gen-parameters-elk.sh <<< "${scriptsDir}/parameters-coherence.json $githubUserName $testbranchName" -parametersList+=(${scriptsDir}/parameters-coherence.json) - -# parameters for cluster+elk -bash ${scriptsDir}/gen-parameters-elk.sh <<< "${scriptsDir}/parameters-elk.json $githubUserName $testbranchName" -parametersList+=(${scriptsDir}/parameters-elk.json) - -# parameters for cluster+db+aad -bash ${scriptsDir}/gen-parameters-db-aad.sh <<< "${scriptsDir}/parameters-db-aad.json $githubUserName $testbranchName" -parametersList+=(${scriptsDir}/parameters-db-aad.json) - # run preflight tests success=true for parameters in "${parametersList[@]}"; diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-services.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-node-services.sh similarity index 96% rename from weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-services.sh rename to weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-node-services.sh index 1b33024f9..9ea5927d6 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-services.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-node-services.sh @@ -31,7 +31,7 @@ function verifyServiceActive() # For admin server : rngd wls_admin wls_nodemanager # For managed server : rngd wls_nodemanager -servicesList=$* +servicesList="rngd wls_nodemanager" for service in $servicesList do diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-servers-lifecycle.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-servers-lifecycle.sh index dd6282746..6c1cbaa50 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-servers-lifecycle.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-servers-lifecycle.sh @@ -1,51 +1,67 @@ -#!/bin/bash # Copyright (c) 2021, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# +# Description +# This script is to test WebLogic cluster domain managed servers lifecycle. -managedServers="#managedServers#" +read wlsUserName wlspassword adminPublicIP adminPort managedServers + +CURL_REQD_PARMS="-s -v --user ${wlsUserName}:${wlspassword} -H X-Requested-By:MyClient -H Content-Type:application/json -H Accept:application/json" +CURL_RETRY_PARMS="--connect-timeout 60 --max-time 180 --retry 10 --retry-delay 30 --retry-max-time 180 --retry-connrefused " # Shutdown the server and verify whether it is in SHUTDOWN state # Restart the managed server for managedServer in $managedServers do - echo "Shut down managed server : $managedServer" - curl --user #wlsUserName#:#wlspassword# -X POST -H 'X-Requested-By: MyClient' -H 'Content-Type: application/json' -H 'Accept: application/json' -i "http://#adminVMName#:7001/management/weblogic/latest/domainRuntime/serverRuntimes/$managedServer/shutdown" --data '{}' - sleep 1m - curl --user #wlsUserName#:#wlspassword# -X GET -H 'X-Requested-By: MyClient' -H 'Content-Type: application/json' -H 'Accept: application/json' -i "http://#adminVMName#:7001/management/weblogic/latest/domainRuntime/serverLifeCycleRuntimes/$managedServer" | grep "\"state\": \"SHUTDOWN\"" - if [ $? != 0 ]; then - echo "$managedServer managed server is not in SHUTDOWN state" - exit 1 - fi - echo "$managedServer managed server is in SHUTDOWN state and starting " - curl --user #wlsUserName#:#wlspassword# -X POST -H 'X-Requested-By: MyClient' -H 'Content-Type: application/json' -H 'Accept: application/json' -i "http://#adminVMName#:7001/management/weblogic/latest/domainRuntime/serverLifeCycleRuntimes/$managedServer/start" --data '{}' - sleep 30s -done + echo "Shut down managed server : $managedServer" + attempt=0 + while [ $attempt -le 5 ] + do + echo "Attempt to shutdown $attempt" + echo curl ${CURL_REQD_PARMS} -X POST -i "http://${adminPublicIP}:${adminPort}/management/weblogic/latest/domainRuntime/serverLifeCycleRuntimes/$managedServer/forceShutdown" --data "{}" + curl ${CURL_REQD_PARMS} -X POST -i "http://${adminPublicIP}:${adminPort}/management/weblogic/latest/domainRuntime/serverLifeCycleRuntimes/$managedServer/forceShutdown" --data "{}" > out + echo "Response received for shutdown REST command" + cat out + echo "Attempt to verify shutdown $attempt" + echo curl ${CURL_REQD_PARMS} ${CURL_RETRY_PARMS} -X GET -i "http://${adminPublicIP}:${adminPort}/management/weblogic/latest/domainRuntime/serverLifeCycleRuntimes/${managedServer}?links=none" + curl ${CURL_REQD_PARMS} ${CURL_RETRY_PARMS} -X GET -i "http://${adminPublicIP}:${adminPort}/management/weblogic/latest/domainRuntime/serverLifeCycleRuntimes/${managedServer}?links=none" > out + echo "Recevied response for shutdown verification" + cat out + cat out | grep "\"state\": \"SHUTDOWN\"" + if [ $? == 0 ]; then + echo "$managedServer managed server is in SHUTDOWN state as expected" + break + elif [[ $? != 0 ]] && [[ $attempt -ge 5 ]]; then + echo "$managedServer managed server is not in SHUTDOWN state after multiple attempts" + exit 1 + fi + attempt=$((attempt+1)) + sleep 30s + done -echo "Wait for few minutes for managed server to restart" -sleep 3m -# Check whether managed server is in RUNNING state -for managedServer in $managedServers -do - echo "Verifying managed server : $managedServer" - isSuccess=false - maxAttempt=3 - attempt=1 - while [ $attempt -le $maxAttempt ] - do - curl --user #wlsUserName#:#wlspassword# -X GET -H 'X-Requested-By: MyClient' -H 'Content-Type: application/json' -H 'Accept: application/json' -i "http://#adminVMName#:7001/management/weblogic/latest/domainRuntime/serverRuntimes/$managedServer" | grep "\"state\": \"RUNNING\"" - if [ $? == 0 ]; then - isSuccess=true - break - fi - attempt=`expr $attempt + 1 ` - sleep 30s - done - if [[ $isSuccess == "false" ]]; then - echo "$managedServer managed server is not in RUNNING state" - exit 1 - else - echo "$managedServer managed server is in RUNNING state" - fi -done + echo "Starting managed server $managedServer" + attempt=0 + while [ $attempt -le 5 ] + do + echo "Attempt to starting server $attempt" + echo curl ${CURL_REQD_PARMS} -X POST -i "http://${adminPublicIP}:${adminPort}/management/weblogic/latest/domainRuntime/serverLifeCycleRuntimes/$managedServer/start" --data "{}" + curl ${CURL_REQD_PARMS} -X POST -i "http://${adminPublicIP}:${adminPort}/management/weblogic/latest/domainRuntime/serverLifeCycleRuntimes/$managedServer/start" --data "{}" > out + echo "Response received for start REST command" + cat out + + echo "Attempt to verify start $attempt" + echo curl ${CURL_REQD_PARMS} ${CURL_RETRY_PARMS} -X GET -i "http://${adminPublicIP}:${adminPort}/management/weblogic/latest/domainRuntime/serverLifeCycleRuntimes/${managedServer}?links=none" + curl ${CURL_REQD_PARMS} ${CURL_RETRY_PARMS} -X GET -i "http://${adminPublicIP}:${adminPort}/management/weblogic/latest/domainRuntime/serverLifeCycleRuntimes/${managedServer}?links=none" > out + echo "Recevied response for start verification" + cat out + cat out | grep "\"state\": \"RUNNING\"" + if [ $? == 0 ]; then + echo "$managedServer managed server is in RUNNING state as expected" + break + elif [[ $retVal != 0 ]] && [[ $attempt -ge 5 ]]; then + echo "$managedServer managed server is not in RUNNING state after multiple attempts" + exit 1 + fi + attempt=$((attempt+1)) + sleep 1m + done +done exit 0 - diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-webapp-deployment.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-webapp-deployment.sh new file mode 100644 index 000000000..cf648f81f --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-webapp-deployment.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Copyright (c) 2021, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +# Description +# This script is to test webapp application deployed on WebLogic cluster domain. + +# Verifying webapp deployment +read appGatewayURL + +CURL_RETRY_PARMS="--connect-timeout 60 --max-time 180 --retry 10 --retry-delay 30 --retry-max-time 180 --retry-connrefused" + +echo "Verifying WebLogic Cafe is deployed as expected" +curl --verbose ${appGatewayURL}weblogic-cafe/rest/coffees +response=$(curl ${CURL_RETRY_PARMS} --write-out '%{http_code}' --silent --output /dev/null ${appGatewayURL}weblogic-cafe/rest/coffees) +echo "$response" +if [ "$response" -ne 200 ]; then + echo "WebLogic Cafe is not accessible" + exit 1 +else + echo "WebLogic Cafe is accessible" +fi +exit 0 diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-wls-access.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-wls-access.sh index 5a3d6f36b..4ff452b00 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-wls-access.sh +++ b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-wls-access.sh @@ -1,70 +1,49 @@ #!/bin/bash + # Copyright (c) 2021, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# +# Description +# This script is to test WebLogic admin, console and managed servers access. + # Verifying admin server is accessible +#read arguments from stdin read adminPublicIP adminPort wlsUserName wlspassword managedServers +CURL_PARMS="--connect-timeout 60 --max-time 180 --retry 10 --retry-delay 30 --retry-max-time 180 --retry-connrefused" -isSuccess=false -maxAttempt=5 -attempt=1 echo "Verifying http://${adminPublicIP}:${adminPort}/weblogic/ready" -while [ $attempt -le $maxAttempt ] -do - echo "Attempt $attempt :- Checking WebLogic admin server is accessible" - curl http://${adminPublicIP}:${adminPort}/weblogic/ready - if [ $? == 0 ]; then - isSuccess=true - break - fi - attempt=`expr $attempt + 1` - sleep 2m -done +curl ${CURL_PARMS} http://${adminPublicIP}:${adminPort}/weblogic/ready -if [[ $isSuccess == "false" ]]; then +if [[ $? != 0 ]]; then echo "Failed : WebLogic admin server is not accessible" exit 1 else echo "WebLogic admin server is accessible" fi -sleep 1m - # Verifying whether admin console is accessible echo "Checking WebLogic admin console is acessible" -curl http://${adminPublicIP}:${adminPort}/console/ +curl ${CURL_PARMS} http://${adminPublicIP}:${adminPort}/console/ if [[ $? != 0 ]]; then echo "WebLogic admin console is not accessible" exit 1 else echo "WebLogic admin console is accessible" + exit 0 fi + #Verifying whether managed servers are up/running for managedServer in $managedServers do echo "Verifying managed server : $managedServer" - isSuccess=false - maxAttempt=3 - attempt=1 - while [ $attempt -le $maxAttempt ] - do - curl --user $wlsUserName:$wlspassword -X GET -H 'X-Requested-By: MyClient' -H 'Content-Type: application/json' -H 'Accept: application/json' -i "http://${adminPublicIP}:${adminPort}/management/weblogic/latest/domainRuntime/serverRuntimes/$managedServer" | grep "\"state\": \"RUNNING\"" - if [ $? == 0 ]; then - isSuccess=true - break - fi - attempt=`expr $attempt + 1 ` - sleep 30s - done - if [[ $isSuccess == "false" ]]; then - echo "$managedServer managed server is not in RUNNING state" - exit 1 + curl ${CURL_PARMS} --user $wlsUserName:$wlspassword -X GET -H 'X-Requested-By: MyClient' -H 'Content-Type: application/json' -H 'Accept: application/json' -i "http://${adminPublicIP}:${adminPort}/management/weblogic/latest/domainRuntime/serverRuntimes/$managedServer" | grep "\"state\": \"RUNNING\"" + if [ $? == 0 ]; then + echo "$managedServer managed server is in RUNNING state" else - echo "$managedServer managed server is in RUNNING state" + echo "$managedServer managed server is not in RUNNING state" + exit 1 fi done exit 0 - diff --git a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-wls-path.sh b/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-wls-path.sh deleted file mode 100644 index dcd3c50b0..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls-dynamic-cluster/test/scripts/verify-wls-path.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -# - -echo "#adminPasswordOrKey#" | sudo -S [ -d "/u01/app/wls/install/oracle/middleware/oracle_home/wlserver/modules" ] && exit 0 -exit 1 - diff --git a/weblogic-azure-vm/arm-oraclelinux-wls/README.md b/weblogic-azure-vm/arm-oraclelinux-wls/README.md index 6e93c209e..019fb22d4 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls/README.md +++ b/weblogic-azure-vm/arm-oraclelinux-wls/README.md @@ -1,6 +1,12 @@ + + ## WebLogic Server installation on Microsoft Azure Virtual Machine - Marketplace Offerings This git repository is used to maintain the Azure Resource Management (ARM) templates and other scripts used for the implementation of WebLogic Server installation on Microsoft Azure. For WebLogic Server running in the Azure Virtual Machines documentation, please refer to the [README documentation](https://github.com/oracle/weblogic-azure/weblogic-azure-vm/README.md). + diff --git a/weblogic-azure-vm/arm-oraclelinux-wls/pom.xml b/weblogic-azure-vm/arm-oraclelinux-wls/pom.xml index 51eb22f62..23650b284 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls/pom.xml +++ b/weblogic-azure-vm/arm-oraclelinux-wls/pom.xml @@ -1,34 +1,37 @@ - + 4.0.0 - com.oracle.weblogic.azure - arm-oraclelinux-wls - 1.0.19 - - com.microsoft.azure.iaas - azure-javaee-iaas-parent - 1.0.7 - + com.oracle.weblogic.azure + weblogic-azure-vm + 1.0.0 + ../pom.xml - + + com.oracle.weblogic.azure + arm-oraclelinux-wls + ${version.arm-oraclelinux-wls} + jar arm-oraclelinux-wls + - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/pid.properties - https://raw.githubusercontent.com/wls-eng/arm-oraclelinux-wls/develop/src/main/resources/microsoft-pid.properties + ${project.parent.basedir}/.. + false + false - + - + diff --git a/weblogic-azure-vm/arm-oraclelinux-wls/src/main/arm/createUiDefinition.json b/weblogic-azure-vm/arm-oraclelinux-wls/src/main/arm/createUiDefinition.json index f43531b44..88c20f542 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls/src/main/arm/createUiDefinition.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls/src/main/arm/createUiDefinition.json @@ -3,34 +3,73 @@ "handler": "Microsoft.Azure.CreateUIDef", "version": "0.1.2-preview", "parameters": { + "config": { + "basics": { + "resourceGroup": { + "allowExisting": true + } + } + }, "basics": [ { "name": "skuUrnVersion", "type": "Microsoft.Common.DropDown", "label": "Oracle WebLogic Image", - "defaultValue": "WebLogic Server 14.1.1.0.0 and JDK11 on Oracle Linux 7.6", + "defaultValue": "WebLogic Server 14.1.2.0.0 and JDK 21 on Oracle Linux 9", "toolTip": "Choose Oracle WebLogic image, which is provided by Oracle, with Java and WebLogic preinstalled.", "constraints": { "allowedValues": [ + { + "label": "WebLogic Server 14.1.2.0.0 and JDK 21 on Oracle Linux 9", + "value": "owls-141200-jdk21-ol94;Oracle:weblogic-141200-jdk21-ol94:owls-141200-jdk21-ol94;latest" + }, + { + "label": "WebLogic Server 14.1.2.0.0 and JDK 21 on Oracle Linux 8", + "value": "owls-141200-jdk21-ol810;Oracle:weblogic-141200-jdk21-ol810:owls-141200-jdk21-ol810;latest" + }, + { + "label": "WebLogic Server 14.1.2.0.0 and JDK 17 on Oracle Linux 9", + "value": "owls-141200-jdk17-ol94;Oracle:weblogic-141200-jdk17-ol94:owls-141200-jdk17-ol94;latest" + }, + { + "label": "WebLogic Server 14.1.2.0.0 and JDK 17 on Oracle Linux 8", + "value": "owls-141200-jdk17-ol810;Oracle:weblogic-141200-jdk17-ol810:owls-141200-jdk17-ol810;latest" + }, { - "label": "WebLogic Server 12.2.1.3.0 and JDK8 on Oracle Linux 7.4", - "value": "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest" + "label": "WebLogic Server 14.1.1.0.0 and JDK 11 on Oracle Linux 9", + "value": "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest" }, { - "label": "WebLogic Server 12.2.1.3.0 and JDK8 on Oracle Linux 7.3", - "value": "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest" + "label": "WebLogic Server 14.1.1.0.0 and JDK 11 on Oracle Linux 8", + "value": "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest" }, { - "label": "WebLogic Server 12.2.1.4.0 and JDK8 on Oracle Linux 7.6", - "value": "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest" + "label": "WebLogic Server 14.1.1.0.0 and JDK 8 on Oracle Linux 9", + "value": "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest" }, { - "label": "WebLogic Server 14.1.1.0.0 and JDK8 on Oracle Linux 7.6", - "value": "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest" + "label": "WebLogic Server 14.1.1.0.0 and JDK 8 on Oracle Linux 8", + "value": "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest" }, { - "label": "WebLogic Server 14.1.1.0.0 and JDK11 on Oracle Linux 7.6", - "value": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" + "label": "WebLogic Server 12.2.1.4.0 and JDK 8 on Oracle Linux 9", + "value": "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest" + }, + { + "label": "WebLogic Server 12.2.1.4.0 and JDK 8 on Oracle Linux 8", + "value": "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK11 on Red Hat Enterprise Linux 8", + "value": "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest" + }, + { + "label": "WebLogic Server 14.1.1.0.0 and JDK8 on Red Hat Enterprise Linux 8", + "value": "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest" + }, + { + "label": "WebLogic Server 12.2.1.4.0 and JDK8 on Red Hat Enterprise Linux 8", + "value": "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest" } ], "required": true @@ -54,13 +93,23 @@ "Standard_B1ls", "Standard_A0", "Basic_A0", - "Standard_B1s" + "Standard_B1s", + ${azure.armBased.vmSize.list} ] }, "osPlatform": "Linux", "count": "1", "visible": true }, + { + "name": "invalidVMSizeInfo", + "type": "Microsoft.Common.InfoBox", + "visible": "[contains(basics('vmSizeSelect'),'p')]", + "options": { + "icon": "Error", + "text": "The VM size you selected includes the feature letter 'p', indicating it uses ARM CPUs. ARM platform is not supported. Please select a different VM size. For more information, refer to the Azure virtual machine sizes naming conventions." + } + }, { "name": "basicsRequired", "type": "Microsoft.Common.Section", @@ -74,8 +123,16 @@ "toolTip": "Use only letters and numbers", "constraints": { "required": true, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "The value must be 1-30 characters long and must only contain letters and numbers." + "validations": [ + { + "regex": "^[a-z0-9A-Z]{1,30}$", + "message": "The value must be 1-30 characters long and must only contain letters and numbers." + }, + { + "isValid": "[not(contains(basics('vmSizeSelect'),'p'))]", + "message": "ARM platform is not supported. Please select a different VM size." + } + ] }, "visible": true }, @@ -179,15 +236,6 @@ }, "defaultValue": "Yes", "visible": "[bool(basics('basicsOptional').basicsOptionalAcceptDefaults)]" - }, - { - "name": "About", - "type": "Microsoft.Common.InfoBox", - "options": { - "icon": "None", - "text": "Template version ${project.version}" - }, - "visible": "[bool('${template.version.visible}')]" } ], "visible": true @@ -197,6 +245,18 @@ "type": "Microsoft.Common.Section", "label": "Report issues, get help, and share feedback", "elements": [ + { + "name": "help", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "See the documentation for this offer.", + "link": { + "label": "Offer documentation", + "uri": "https://aka.ms/wls-vm-docs" + } + } + }, { "name": "howToReportIssueText", "type": "Microsoft.Common.TextBlock", @@ -205,7 +265,7 @@ "text": "If you encounter problems during the deployment of Oracle WebLogic Server, report them here.", "link": { "label": "Issue tracker", - "uri": "https://aka.ms/arm-oraclelinux-wls-issues" + "uri": "https://aka.ms/arm-oraclelinux-wls-issues?version=${project.version}" } } }, @@ -237,7 +297,28 @@ "visible": true } ], - "steps":[], + "steps":[ + { + "name": "tags", + "label": "Tags", + "elements": [ + { + "name": "tagsByResource", + "type": "Microsoft.Common.TagsByResource", + "resources": [ + "${identifier.virtualMachines}", + "${identifier.virtualNetworks}", + "${identifier.networkInterfaces}", + "${identifier.networkSecurityGroups}", + "${identifier.publicIPAddresses}", + "${identifier.storageAccounts}", + "${identifier.resourcesDeployment}" + ], + "toolTip": "Tags help you organize your resources and categorize them for billing or management purposes. You can apply tags to resources deployed by the offer." + } + ] + } + ], "outputs": { "adminPasswordOrKey": "[if(equals(basics('basicsRequired').adminPasswordOrKey.authenticationType, 'password'), basics('basicsRequired').adminPasswordOrKey.password, basics('basicsRequired').adminPasswordOrKey.sshPublicKey)]", "adminUsername": "[basics('basicsRequired').adminUsername]", @@ -245,8 +326,9 @@ "dnsLabelPrefix": "[basics('basicsOptional').dnsLabelPrefix]", "portsToExpose": "[basics('basicsOptional').portsToExpose]", "skuUrnVersion": "[basics('skuUrnVersion')]", + "tagsByResource": "[steps('tags').tagsByResource]", "useSystemAssignedManagedIdentity": "[basics('basicsOptional').useSystemAssignedManagedIdentity]", - "vmSizeSelect": "[basics('vmSizeSelect')]", + "vmSize": "[basics('vmSizeSelect')]", "Location": "[location()]" } } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls/src/main/arm/mainTemplate.json b/weblogic-azure-vm/arm-oraclelinux-wls/src/main/arm/mainTemplate.json index ca0a8271c..190909ada 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls/src/main/arm/mainTemplate.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls/src/main/arm/mainTemplate.json @@ -52,18 +52,33 @@ }, "skuUrnVersion": { "type": "string", - "defaultValue": "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest", + "defaultValue": "owls-141200-jdk21-ol94;Oracle:weblogic-141200-jdk21-ol94:owls-141200-jdk21-ol94;latest", "allowedValues": [ - "owls-122130-jdk8-ol73;Oracle:weblogic-122130-jdk8-ol73:owls-122130-jdk8-ol7;latest", - "owls-122130-jdk8-ol74;Oracle:weblogic-122130-jdk8-ol74:owls-122130-jdk8-ol7;latest", - "owls-122140-jdk8-ol76;Oracle:weblogic-122140-jdk8-ol76:owls-122140-jdk8-ol7;latest", - "owls-141100-jdk8-ol76;Oracle:weblogic-141100-jdk8-ol76:owls-141100-jdk8-ol7;latest", - "owls-141100-jdk11-ol76;Oracle:weblogic-141100-jdk11-ol76:owls-141100-jdk11-ol7;latest" + "owls-141200-jdk21-ol94;Oracle:weblogic-141200-jdk21-ol94:owls-141200-jdk21-ol94;latest", + "owls-141200-jdk21-ol810;Oracle:weblogic-141200-jdk21-ol810:owls-141200-jdk21-ol810;latest", + "owls-141200-jdk17-ol94;Oracle:weblogic-141200-jdk17-ol94:owls-141200-jdk17-ol94;latest", + "owls-141200-jdk17-ol810;Oracle:weblogic-141200-jdk17-ol810:owls-141200-jdk17-ol810;latest", + "owls-141100-jdk11-ol91;Oracle:weblogic-141100-jdk11-ol91:owls-141100-jdk11-ol91;latest", + "owls-141100-jdk11-ol87;Oracle:weblogic-141100-jdk11-ol87:owls-141100-jdk11-ol87;latest", + "owls-141100-jdk8-ol91;Oracle:weblogic-141100-jdk8-ol91:owls-141100-jdk8-ol91;latest", + "owls-141100-jdk8-ol87;Oracle:weblogic-141100-jdk8-ol87:owls-141100-jdk8-ol87;latest", + "owls-122140-jdk8-ol91;Oracle:weblogic-122140-jdk8-ol91:owls-122140-jdk8-ol91;latest", + "owls-122140-jdk8-ol87;Oracle:weblogic-122140-jdk8-ol87:owls-122140-jdk8-ol87;latest", + "owls-141100-jdk11-rhel87;Oracle:weblogic-141100-jdk11-rhel87:owls-141100-jdk11-rhel87;latest", + "owls-141100-jdk8-rhel87;Oracle:weblogic-141100-jdk8-rhel87:owls-141100-jdk8-rhel87;latest", + "owls-122140-jdk8-rhel87;Oracle:weblogic-122140-jdk8-rhel87:owls-122140-jdk8-rhel87;latest" ], "metadata": { "description": "The Oracle Linux image with Weblogic and Java preinstalled. Semicolon separated string of Sku, URN, and Version" } }, + "tagsByResource": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "${label.tagsLabel}" + } + }, "usePreviewImage": { "type": "bool", "defaultValue": false, @@ -85,7 +100,7 @@ "description": "VM name." } }, - "vmSizeSelect": { + "vmSize": { "type": "string", "defaultValue": "Standard_A3", "metadata": { @@ -95,6 +110,7 @@ }, "variables": { "const_addressPrefix": "10.0.0.0/16", + "const_globalResourceNameSuffix": "[uniqueString(parameters('guidValue'))]", "const_hyphen": "-", "const_imageOffer": "[concat('weblogic',variables('const_hyphen'), split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[1],variables('const_hyphen'),split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[2],variables('const_hyphen'),split(variables('name_linuxImageOfferSKU'),variables('const_hyphen'))[3],if(parameters('usePreviewImage'),'-preview',''))]", "const_imagePublisher": "oracle", @@ -113,22 +129,49 @@ "const_requiredPortrange": ",65200-65535,5556", "const_storageAccountType": "Standard_LRS", "const_subnetPrefix": "10.0.0.0/24", - "const_vmSize": "[parameters('vmSizeSelect')]", + "const_vmSize": "[parameters('vmSize')]", "name_linuxImageOfferSKU": "[first(split(parameters('skuUrnVersion'), ';'))]", "name_linuxImageVersion": "[last(split(parameters('skuUrnVersion'),';'))]", - "name_networkSecurityGroup": "[concat(parameters('dnsLabelPrefix'), '-nsg')]", - "name_nic": "olvm_NIC", - "name_publicIPAddress": "olvm_PublicIP", - "name_storageAccount": "[concat(take(replace(parameters('guidValue'),'-',''),6),'olvm')]", + "name_networkSecurityGroup": "[concat(parameters('dnsLabelPrefix'), '-nsg_', variables('const_globalResourceNameSuffix'))]", + "name_nic": "[concat('olvm_NIC_', variables('const_globalResourceNameSuffix'))]", + "name_publicIPAddress": "[concat('olvm_PublicIP_', variables('const_globalResourceNameSuffix'))]", + "name_storageAccount": "[concat('olvmstg', variables('const_globalResourceNameSuffix'))]", "name_subnet": "Subnet", - "name_virtualNetwork": "olvm_VNET", + "name_virtualNetwork": "[concat('olvm_VNET_', variables('const_globalResourceNameSuffix'))]", + "name_vmName": "[concat(parameters('vmName'), variables('const_globalResourceNameSuffix'))]", "ref_networkSecurityGroup": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('name_networkSecurityGroup'))]", "ref_subnet": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('name_virtualNetwork'), variables('name_subnet'))]" }, + "functions": [ + { + // This same function is defined in the mainTemplate.json for every other offer. + // Please ensure any changes are applied in all the other places. + "namespace": "funcTags", + "members": { + "tagsFilter": { + "parameters": [ + { + "name": "tagsByResource", + "type": "object" + }, + { + "name": "resourceIdentifier", + "type": "string" + } + ], + "output": { + "type": "object", + "value": "[if(contains(parameters('tagsByResource'), parameters('resourceIdentifier')), parameters('tagsByResource')[parameters('resourceIdentifier')], json('{}'))]" + } + } + } + } + ], "resources": [ { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", "name": "${start}", "properties": { "mode": "Incremental", @@ -141,7 +184,8 @@ }, { "type": "Microsoft.Network/networkSecurityGroups", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForNetworkSecurityGroups}", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.networkSecurityGroups}')]", "name": "[variables('name_networkSecurityGroup')]", "location": "[parameters('location')]", "properties": { @@ -164,7 +208,8 @@ }, { "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "${azure.apiVersion2}", + "apiVersion": "${azure.apiVersionForStorage}", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.storageAccounts}')]", "name": "[variables('name_storageAccount')]", "location": "[parameters('location')]", "sku": { @@ -174,8 +219,9 @@ "properties": {} }, { + "apiVersion": "${azure.apiVersionForPublicIPAddresses}", "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "${azure.apiVersion}", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.publicIPAddresses}')]", "name": "[variables('name_publicIPAddress')]", "location": "[parameters('location')]", "properties": { @@ -186,8 +232,9 @@ } }, { + "apiVersion": "${azure.apiVersionForVirtualNetworks}", "type": "Microsoft.Network/virtualNetworks", - "apiVersion": "${azure.apiVersion}", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.virtualNetworks}')]", "name": "[variables('name_virtualNetwork')]", "location": "[parameters('location')]", "dependsOn": [ @@ -213,8 +260,9 @@ } }, { + "apiVersion": "${azure.apiVersionForNetworkInterfaces}", "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "${azure.apiVersion}", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.networkInterfaces}')]", "name": "[variables('name_nic')]", "location": "[parameters('location')]", "dependsOn": [ @@ -237,14 +285,15 @@ } ], "dnsSettings": { - "internalDnsNameLabel": "[parameters('vmName')]" + "internalDnsNameLabel": "[variables('name_vmName')]" } } }, { + "apiVersion": "${azure.apiVersionForVirtualMachines}", "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "${azure.apiVersion}", - "name": "[parameters('vmName')]", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'), '${identifier.virtualMachines}')]", + "name": "[variables('name_vmName')]", "location": "[parameters('location')]", "dependsOn": [ "[resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount'))]", @@ -256,7 +305,7 @@ "vmSize": "[variables('const_vmSize')]" }, "osProfile": { - "computerName": "[parameters('vmName')]", + "computerName": "[variables('name_vmName')]", "adminUsername": "[parameters('adminUsername')]", "adminPassword": "[parameters('adminPasswordOrKey')]", "linuxConfiguration": "[if(equals(parameters('authenticationType'), 'password'), json('null'), variables('const_linuxConfiguration'))]" @@ -273,17 +322,7 @@ "managedDisk": { "storageAccountType": "[variables('const_storageAccountType')]" } - }, - "dataDisks": [ - { - "lun": 0, - "createOption": "FromImage", - "diskSizeGB": 900, - "managedDisk": { - "storageAccountType": "[variables('const_storageAccountType')]" - } - } - ] + } }, "networkProfile": { "networkInterfaces": [ @@ -295,7 +334,7 @@ "diagnosticsProfile": { "bootDiagnostics": { "enabled": true, - "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount')), '${azure.apiVersion2}').primaryEndpoints.blob]" + "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('name_storageAccount')), '${azure.apiVersionForStorage}').primaryEndpoints.blob]" } } }, @@ -306,11 +345,12 @@ } }, { - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${end}", "type": "Microsoft.Resources/deployments", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/', parameters('vmName'))]" + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" ], "properties": { "mode": "Incremental", @@ -322,12 +362,146 @@ } }, { - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-122130-jdk8-ol74}", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141200-jdk21-ol94}", + "type": "Microsoft.Resources/deployments", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk21-ol94'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141200-jdk21-ol810}", + "type": "Microsoft.Resources/deployments", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk21-ol810'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141200-jdk17-ol94}", + "type": "Microsoft.Resources/deployments", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk17-ol94'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141200-jdk17-ol810}", + "type": "Microsoft.Resources/deployments", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141200-jdk17-ol810'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk11-ol91}", + "type": "Microsoft.Resources/deployments", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol91'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk11-ol87}", + "type": "Microsoft.Resources/deployments", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol87'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk8-ol91}", + "type": "Microsoft.Resources/deployments", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol91'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk8-ol87}", "type": "Microsoft.Resources/deployments", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122130-jdk8-ol74'), bool('true'), bool('false'))]", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol87'), bool('true'), bool('false'))]", "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/', parameters('vmName'))]" + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" ], "properties": { "mode": "Incremental", @@ -340,12 +514,13 @@ } }, { - "apiVersion": "${azure.apiVersion}", - "name": "${from.owls-122130-jdk8-ol73}", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-122140-jdk8-ol91}", "type": "Microsoft.Resources/deployments", - "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'from.owls-122130-jdk8-ol73'), bool('true'), bool('false'))]", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-ol91'), bool('true'), bool('false'))]", "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/', parameters('vmName'))]" + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" ], "properties": { "mode": "Incremental", @@ -358,12 +533,32 @@ } }, { + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-122140-jdk8-ol87}", "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-ol87'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${from.owls-122140-jdk8-ol76}", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'from.owls-122140-jdk8-ol76'), bool('true'), bool('false'))]", "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/', parameters('vmName'))]" + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" ], "properties": { "mode": "Incremental", @@ -377,11 +572,12 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${from.owls-141100-jdk8-ol76}", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-ol76'), bool('true'), bool('false'))]", "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/', parameters('vmName'))]" + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" ], "properties": { "mode": "Incremental", @@ -395,11 +591,126 @@ }, { "type": "Microsoft.Resources/deployments", - "apiVersion": "${azure.apiVersion}", + "apiVersion": "${azure.apiVersionForDeployment}", "name": "${from.owls-141100-jdk11-ol76}", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-ol76'), bool('true'), bool('false'))]", "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines/', parameters('vmName'))]" + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-122140-jdk8-rhel87}", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-rhel87'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk8-rhel87}", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-rhel87'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk11-rhel87}", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-rhel87'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-122140-jdk8-rhel76}", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-122140-jdk8-rhel76'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk8-rhel76}", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk8-rhel76'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "${azure.apiVersionForDeployment}", + "name": "${from.owls-141100-jdk11-rhel76}", + "tags": "[funcTags.tagsFilter(parameters('tagsByResource'),'${identifier.resourcesDeployment}')]", + "condition": "[if(contains(variables('name_linuxImageOfferSKU'), 'owls-141100-jdk11-rhel76'), bool('true'), bool('false'))]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/', variables('name_vmName'))]" ], "properties": { "mode": "Incremental", diff --git a/weblogic-azure-vm/arm-oraclelinux-wls/src/main/arm/olvmdeploy.parameters.json b/weblogic-azure-vm/arm-oraclelinux-wls/src/main/arm/olvmdeploy.parameters.json index 42f9b1695..b04d054f2 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls/src/main/arm/olvmdeploy.parameters.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls/src/main/arm/olvmdeploy.parameters.json @@ -11,7 +11,7 @@ "dnsLabelPrefix": { "value": "GEN-UNIQUE" }, - "vmSizeSelect":{ + "vmSize":{ "value": "GEN-UNIQUE" } } diff --git a/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/README.md b/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/README.md index f0d1d8526..9cb7b0006 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/README.md +++ b/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/README.md @@ -1,14 +1,156 @@ + + +# Offer setup + +## Alias + +Oracle WebLogic Server on Azure Solution Overview + +## Setup details + +* No, I would prefer to only list my offer through the marketplace and process transactions independently + +* How do you want potential customers to interact with this listing offer? + + * Contact me + +### Test drive + +* Not checked Enable a test drive + +### Customer leads + +CRM System connected + +* HTTPS Endpoint + +* Contact email + + * jacob.x.thomas@oracle.com;edburns@microsoft.com;rezar@microsoft.com + +* HTTPS endpoint URL + + * https://prod-15.westcentralus.logic.azure.com:443/workflows/9024092aefba434c9db98dc2536423f6/triggers/manual/paths/invoke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=SggEKOTUpII26Oc6XYVl7nbSgluiYdVeIXkq19LuTtY + +### Microsoft 365 integration + +* No, my SaaS offer does not integrate with Microsoft Graph + +* No, I do not have published Teams apps, Office add-ins, or SharePoint Framework solutions that I would like to link to this SaaS offer + +# Properties + +## Categories + +* Primary category: Compute + + * Subcategory: Application Infrastructure + +* Secondary category: Web + + * Subcategory: Web Apps + +## Industries + +* Checked Apps + +* Not checked Microsoft Clouds for Industry + +* App version: Various + +## Legal + +* Checked Use the Standarard Contract for Microsoft's commercial marketplace? + +## Custom amendments... + +No content. + # What is this stuff? -Useful Links to documentation, video, blog of WebLogic on Azure IaaS. +Useful Links to documentation, video, blog of WebLogic on Azure. + +# Offer Listing + +## Name + +Oracle WebLogic Server on Azure Solution Overview + +## Search results summary + +Oracle WebLogic Server is a scalable, enterprise-ready Java application server. + +## Description (Observed max 2973 characters, not including formatting) + +

    Oracle WebLogic Server (WLS) on Azure offers enable you to embrace cloud computing by making it as easy as possible to migrate your Java applications to Azure. The offers increase productivity by automating most boilerplate Java and Azure resource provisioning and configuration tasks so that you can focus on application development. The offers cover deployment to both Azure Virtual Machines and the Azure Kubernetes Service (AKS).

    + +

    The offers are linked in the Learn more section at the bottom of this page.

    + +

    These offers are Bring-Your-Own-License. They assume you have already procured the appropriate licenses with Oracle and are properly licensed to run offers in Azure.

    + +

    If you want to work closely on your migration scenarios with the engineering team developing these offers, just hit the CONTACT ME button. Program managers, architects and engineers will reach back out to you shortly and initiate collaboration!

    + +

    WebLogic Server on Virtual Machines
    +The WebLogic Server on virtual machines offers automate provisioning virtual network, storage, and Linux resources, installing WLS, setting up security with a network security group, easing database connectivity, configuring load-balancing with App Gateway or Oracle HTTP Server, connecting to Azure Active Directory, enabling centralized logging via ELK as well as integrating distributed caching with Oracle Coherence.

    + +

    There are several offers that target use cases such as single node with Administration server enabled and WLS cluster (including both configured and dynamic clusters). These offers supports a range of operating system, Java and WebLogic versions such as WLS 14.1.1.0 and JDK 11 on Oracle Linux through base images. These base images are also available on Azure on their own. The base images are suitable for customers that require very highly customized Azure deployments. The current set of base images are available in the Azure marketplace.

    + +

    WebLogic Server on AKS
    +The WebLogic Server on AKS offer automates provisioning an AKS cluster, the WebLogic Kubernetes Operator, WLS Docker images and the Azure Container Registry (ACR). The offer also supports configuring load balancing with Azure App Gateway or the Azure Load Balancer, easing database connectivity, publishing metrics to Azure Monitor as well as mounting Azure Files as Kubernetes Persistent Volumes. The offer will work with any WLS version that supports the Operator, such as 14.1.2.0, 14.1.1.0, and 12.2.1.4.

    + +

    Oracle and Microsoft also provide basic step-by-step guidance on getting started with WLS and AKS. This guidance is suitable for customers that wish to remain as close as possible to a native Kubernetes manual deployment experience.

    + +## Getting Started Instructions + +Blank + +## Search keywords + +Java WLS WebLogic + +## Privacy policy link + +https://www.oracle.com/legal/privacy/privacy-policy.html + ## Useful Links -* [Overview](http://www.oracle.com/weblogicserver) +* [Oracle WebLogic Overview](https://www.oracle.com/middleware/weblogic/) + +* [Oracle WebLogic Server Single Node](https://portal.azure.com/#create/oracle.20191001-arm-oraclelinux-wls20191001-arm-oraclelinux-wls) + +* [Oracle WebLogic Server With Administration Server](https://portal.azure.com/#create/oracle.20191009-arm-oraclelinux-wls-admin20191009-arm-oraclelinux-wls-admin) + +* [Oracle WebLogic Server Cluster](https://portal.azure.com/#create/oracle.20191007-arm-oraclelinux-wls-cluster20191007-arm-oraclelinux-wls-cluster) + +* [Oracle WebLogic Server Dynamic Cluster](https://portal.azure.com/#create/oracle.20191021-arm-oraclelinux-wls-dynamic-cluster20191021-arm-oraclelinux-wls-dynamic-cluster) + +* [Weblogic on Azure VMs Offer Documentation](https://oracle.github.io/weblogic-azure/) + +* [WebLogic on Azure Kubernetes Service](https://portal.azure.com/#create/oracle.20210620-wls-on-aks20210620-wls-on-aks) + +* [WebLogic on Azure Kubernetes Service Offer Documentation](https://aka.ms/wls-aks-docs) + +* [Fusion Middleware Documentation](https://docs.oracle.com/en/middleware/fusion-middleware/index.html) + +* [Learn More](https://www.oracle.com/middleware/technologies/weblogic.html) + +## Supporting Documents + +* Release Notes + + * PDF download of WLS Release Notes + +## Videos + +* [WebLogic on Azure IaaS](https://www.youtube.com/watch?v=KZpG280G_vs) -* [Learn more](http://www.oracle.com/technetwork/middleware/weblogic/learnmore/index.html) +## Scratch not currently in offer -* [Documentation](https://wls-eng.github.io/arm-oraclelinux-wls/) +* [Documentation](https://oracle.github.io/weblogic-azure/) * [Official Blog](https://blogs.oracle.com/weblogicserver/) diff --git a/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/description.html b/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/description.html deleted file mode 100644 index beb96a97f..000000000 --- a/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/description.html +++ /dev/null @@ -1 +0,0 @@ -

    Oracle WebLogic Server 12c is a scalable, enterprise-ready Java EE 7 application server.

    Oracle WebLogic Server is the best application server for building and deploying enterprise Java EE 7 applications with support for new features for lowering cost of operations, improving performance, enhancing scalability and supporting the Oracle Applications portfolio.

    For documentation on this and other WebLogic Server on Microsoft Azure IaaS offers, see the official documentation.

    WebLogic implements the following standards.
    StandardVersion

    Batch

    1.0

    CDI

    1.1

    Dependency Injection

    1.0

    Concurrent Managed Objects

    1.0

    Expression Language (EL)

    3.0, 2.2, 2.1, 2.0

    JSON Processing

    1.0

    XML Web Services (JAX-WS)

    2.2, 2.1, 2.0

    REST (JAX-RS)

    2.0

    WebSocket

    1.1

    JavaBeans Activation Framework

    1.1

    Java EE

    7.0

    Application Deployment

    1.2

    Bean Validation

    1.1

    Common Annotations

    1.2

    Connectors

    1.7

    EJB

    3.2, 3.1, 3.0, 2.1, 2.0, and 1.1

    Web Services

    1.3, 1.2, 1.1

    Interceptors

    1.2

    JDBC

    4.0, 3.0

    JMS

    2.0, 1.1, 1.0.2b

    JNDI

    1.2

    JSF

    2.2, 2.1.*, 2.0, 1.2, 1.1

    JSP

    2.3, 2.2, 2.1, 2.0, 1.2, and 1.1

    Managed Beans

    1.0

    Servlet

    3.1, 3.0, 2.5, 2.4, 2.3, and 2.2

    Java RMI

    1.0

    JavaMail

    1.5

    JTA

    1.2

    JAX-B

    2.2, 2.1, 2.0

    JAX-P

    1.3, 1.2, 1.1

    JAX-R

    1.0

    JAX-RPC

    1.1

    JMX

    2.0

    JPA

    2.1, 2.0., 1.0

    Management

    1.1

    JSTL

    1.2

    Managed Beans

    1.0

    OTS/JTA

    OTS 1.2 and JTA 1.2

    RMI/IIOP

    1.0

    SOAP Attachments (SAAJ)

    1.3, 1.2

    Streaming API for XML (StAX)

    1.0

    Web Services Metadata

    2.0, 1.1

    diff --git a/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/marketing-artifacts/README.md b/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/marketing-artifacts/README.md index 2a9211287..ac2e7643d 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/marketing-artifacts/README.md +++ b/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/marketing-artifacts/README.md @@ -1,3 +1,8 @@ + +

    Offer listing

    Name

    @@ -32,6 +37,7 @@ WebLogic https://www.oracle.com/legal/privacy/privacy-policy.html +

    Useful links

    [Overview](https://www.oracle.com/middleware/weblogic/) @@ -60,4 +66,4 @@ https://www.youtube.com/watch?v=gFS-64XQorA

    Thumbnail

    - + \ No newline at end of file diff --git a/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/marketing-artifacts/base-images.html b/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/marketing-artifacts/base-images.html index 07e797f93..aac2be19c 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/marketing-artifacts/base-images.html +++ b/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/marketing-artifacts/base-images.html @@ -82,3 +82,7 @@

    Customer support links

    https://support.oracle.com/portal/ +

    License

    +Copyright (c) 2021, Oracle and/or its affiliates. +

    +Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. diff --git a/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/marketing-artifacts/partner-center.html b/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/marketing-artifacts/partner-center.html new file mode 100644 index 000000000..c8150585a --- /dev/null +++ b/weblogic-azure-vm/arm-oraclelinux-wls/src/main/resources/marketing-artifacts/partner-center.html @@ -0,0 +1,43 @@ +

    Name

    +

    Oracle WebLogic Server Single Node on Azure VM

    +

    Search results summary

    +

    Provisions a Single Node Oracle WebLogic Server on an Azure VM.

    +

    Short description

    +

    Create a single virtual machine with WebLogic pre-installed.

    +

    Description

    +

    Oracle WebLogic Server (WLS) is an industry-leading Java runtime powering some of the most mission-critical enterprise applications + across the globe. This solution automates most boilerplate steps to provision a single WLS node on an Azure VM. No domain is created and + no Admin Server is started. The offer is useful for scenarios with highly customized domain configuration. Once initial provisioning is + complete, you are completely free to customize deployments further. The solution is jointly developed by Oracle and Microsoft.

    +

    WLS Enterprise Edition versions supported include 12.2.1.4, 14.1.1.0 and 14.1.2.0 .

    +

    The following resources are automatically provisioned by the offer.

    +
      +
    • Oracle Linux or Red Hat Enterprise Linux (RHEL) VM with public IP address
    • +
    • Single WLS Enterprise Edition instance (ORACLE_HOME is +/u01/app/wls/install/oracle/middleware/oracle_home)
    • +
    • Oracle JDK (JAVA_HOME is /u01/app/jdk/jdk-${version})
    • +
    • In addition to drivers that come standard with WLS, most recent supported PostgreSQL and Microsoft SQL JDBC drivers (drivers stored in +/u01/app/wls/install/oracle/middleware/oracle_home/wlserver/server/lib/)
    • +
    • Virtual network and subnet (alternatively, you can deploy to an existing virtual network)
    • +
    • Network security group
    • +
    • OS disk attached to VM
    • +
    • Azure Storage Account to store VM diagnostics
    • +
    +

    This offer is Bring-Your-Own-License. It assumes you have already procured the appropriate licenses with Oracle and are properly +licensed to run offers in Microsoft Azure.

    +

    Oracle and Microsoft also provide basic step-by-step instructions on getting started with WLS and Azure VMs without automated +provisioning.

    +

    Oracle and Microsoft provide similar solutions targeting WLS on the Azure Kubernetes Service (AKS) in addition to Azure VMs +(single instance or cluster). These options are linked in the Learn more section below.

    +

    You can reach out to the engineering team developing these offers by clicking the CONTACT ME button on +the marketplace WebLogic on Azure overview page. Program managers, architects and engineers will get in touch and can +assist you for free with your Azure migration.

    +

    Links

    + diff --git a/weblogic-azure-vm/arm-oraclelinux-wls/test/data/parameters-test.json b/weblogic-azure-vm/arm-oraclelinux-wls/test/data/parameters-test.json index e54998e1b..14b6a3e73 100644 --- a/weblogic-azure-vm/arm-oraclelinux-wls/test/data/parameters-test.json +++ b/weblogic-azure-vm/arm-oraclelinux-wls/test/data/parameters-test.json @@ -1,5 +1,5 @@ { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "adminUsername": { @@ -14,7 +14,7 @@ "skuUrnVersion": { "value":"#skuUrnVersion#" }, - "vmSizeSelect": { + "vmSize": { "value": "Standard_D2as_v4" }, "location": { diff --git a/weblogic-azure-vm/pom.xml b/weblogic-azure-vm/pom.xml new file mode 100644 index 000000000..616d7d289 --- /dev/null +++ b/weblogic-azure-vm/pom.xml @@ -0,0 +1,38 @@ + + + + + 4.0.0 + + + com.oracle.weblogic.azure + weblogic-azure + 1.0.0 + + + com.oracle.weblogic.azure + weblogic-azure-vm + pom + 1.0.0 + ${project.artifactId} + https://github.com/oracle/weblogic-azure/tree/main/weblogic-azure-vm + + + ${project.basedir}/.. + + + + arm-oraclelinux-wls + arm-oraclelinux-wls-admin + arm-oraclelinux-wls-cluster + arm-oraclelinux-wls-dynamic-cluster + + + diff --git a/weblogic-azure-vm/utilities/custom-hostname-verifier/generateCustomHostNameVerifier.sh b/weblogic-azure-vm/utilities/custom-hostname-verifier/generateCustomHostNameVerifier.sh new file mode 100755 index 000000000..9562dec0b --- /dev/null +++ b/weblogic-azure-vm/utilities/custom-hostname-verifier/generateCustomHostNameVerifier.sh @@ -0,0 +1,124 @@ +#!/bin/bash + +function usage() +{ + echo "Usage: $0 []" + exit 1 +} + + +function readArgs() +{ + + if [ $# -lt 6 ]; + then + echo "Error !! invalid arguments" + usage + fi + + adminInternalHostName="$1" + adminExternalHostName="$2" + adminDNSZoneName="$3" + dnsLabelPrefix="$4" + wlsDomainName="$5" + azureResourceGroupRegion="$6" + adminVMNamePrefix=$7 + globalResourceNameSuffix="$8" + + if [ $# -gt 8 ]; + then + debugFlag="$9" + else + debugFlag="false" + fi + +} + + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + +java -version > /dev/null 2>&1 + +if [ $? != 0 ]; +then + echo -e "Error !! This script requires java to be installed and available in the path for execution. \n Please install and configure JAVA in PATH variable and retry" + exit 1 +fi + +if [ -z $WL_HOME ]; +then + echo -e "Error !! WL_HOME is not set. \nPlease ensure that WebLogic Server is installed and WL_HOME variable is set to the WebLogic Home Directory" + exit 1 +fi + +#main + +readArgs "$@" + +echo "initializing ..." +CLASSES_DIR="$SCRIPT_DIR/classes" +mkdir -p "$CLASSES_DIR" + +OUTPUT_DIR="$SCRIPT_DIR/output" +mkdir -p "$OUTPUT_DIR" + +echo "Copying HostNames Template file ..." +cp -rf $SCRIPT_DIR/src/main/java/HostNameValuesTemplate.txt $SCRIPT_DIR/src/main/java/HostNameValues.java + +cd $SCRIPT_DIR/src/main/java +echo "Compiling Default HostNameValues.java ..." +$JAVA_HOME/bin/javac -d $CLASSES_DIR HostNameValues.java + +echo "Compiling WebLogicCustomHostNameVerifier.java " +$JAVA_HOME/bin/javac -d $CLASSES_DIR -classpath $WL_HOME/server/lib/weblogic.jar:$CLASSES_DIR WebLogicCustomHostNameVerifier.java + +echo "generating weblogicustomhostnameverifier.jar" +cd $CLASSES_DIR +jar cf $OUTPUT_DIR/weblogicustomhostnameverifier.jar com/oracle/azure/weblogic/security/util/*.class + +#replace arg values in HostNameValues.java +cp $SCRIPT_DIR/src/main/java/HostNameValues.java $SCRIPT_DIR/src/main/java/HostNameValues.java.bak +sed -i "s/debugEnabled=.*/debugEnabled=${debugFlag};/g" $SCRIPT_DIR/src/main/java/HostNameValues.java +sed -i "s/adminInternalHostName=.*/adminInternalHostName=\"${adminInternalHostName}\";/g" $SCRIPT_DIR/src/main/java/HostNameValues.java +sed -i "s/adminExternalHostName=.*/adminExternalHostName=\"${adminExternalHostName}\";/g" $SCRIPT_DIR/src/main/java/HostNameValues.java +sed -i "s/adminDNSZoneName=.*/adminDNSZoneName=\"${adminDNSZoneName}\";/g" $SCRIPT_DIR/src/main/java/HostNameValues.java +sed -i "s/dnsLabelPrefix=.*/dnsLabelPrefix=\"${dnsLabelPrefix}\";/g" $SCRIPT_DIR/src/main/java/HostNameValues.java +sed -i "s/wlsDomainName=.*/wlsDomainName=\"${wlsDomainName}\";/g" $SCRIPT_DIR/src/main/java/HostNameValues.java +sed -i "s/azureResourceGroupRegion=.*/azureResourceGroupRegion=\"${azureResourceGroupRegion}\";/g" $SCRIPT_DIR/src/main/java/HostNameValues.java +sed -i "s/globalResourceNameSuffix=.*/globalResourceNameSuffix=\"${globalResourceNameSuffix}\";/g" $SCRIPT_DIR/src/main/java/HostNameValues.java +sed -i "s/adminVMNamePrefix=.*/adminVMNamePrefix=\"${adminVMNamePrefix}\";/g" $SCRIPT_DIR/src/main/java/HostNameValues.java + + +cd $SCRIPT_DIR/src/main/java +echo "Compiling modified HostNameValues.java ..." +$JAVA_HOME/bin/javac -d $CLASSES_DIR HostNameValues.java + +echo "generating hostnamevalues.jar" +cd $CLASSES_DIR +jar cf $OUTPUT_DIR/hostnamevalues.jar com/oracle/azure/weblogic/*.class + +if [ $? != 0 ]; +then + echo "CustomHostNameVerifier jar creation Failed !! Please check the error and retry." + exit 1 +else + echo "CustomHostNameVerifier jar created Successfully !!" +fi + +echo "cleaning up existing classes ..." +find $CLASSES_DIR -type f -name "*.class" -delete + +echo "Running HostNameVerifierTest ..." +cd $SCRIPT_DIR/src/test/java +$JAVA_HOME/bin/javac -d $CLASSES_DIR -classpath $OUTPUT_DIR/hostnamevalues.jar:$OUTPUT_DIR/weblogicustomhostnameverifier.jar WebLogicCustomHostNameVerifierTest.java + +$JAVA_HOME/bin/java -classpath $CLASSES_DIR:$OUTPUT_DIR/hostnamevalues.jar:$OUTPUT_DIR/weblogicustomhostnameverifier.jar com.oracle.azure.weblogic.security.test.WebLogicCustomHostNameVerifierTest "$@" + +if [ $? != 0 ]; +then + echo "CustomHostNameVerifierTest Failed !! Please check the error and retry." + exit 1 +else + echo "CustomHostNameVerifierTest Passed Successfully !!" +fi + diff --git a/weblogic-azure-vm/utilities/custom-hostname-verifier/src/main/java/HostNameValuesTemplate.txt b/weblogic-azure-vm/utilities/custom-hostname-verifier/src/main/java/HostNameValuesTemplate.txt new file mode 100644 index 000000000..a6245dcc2 --- /dev/null +++ b/weblogic-azure-vm/utilities/custom-hostname-verifier/src/main/java/HostNameValuesTemplate.txt @@ -0,0 +1,62 @@ +package com.oracle.azure.weblogic; + +public class HostNameValues +{ + public static final String azureVMExternalDomainName="cloudapp.azure.com"; + + private static boolean debugEnabled=false; + private static String adminInternalHostName=""; + private static String adminExternalHostName=""; + private static String adminDNSZoneName=""; + private static String dnsLabelPrefix=""; + private static String wlsDomainName=""; + private static String azureResourceGroupRegion=""; + private static String globalResourceNameSuffix=""; + private static String adminVMNamePrefix=""; + + public static boolean isDebugEnabled() + { + return debugEnabled; + } + + public static String getAdminInternalHostName() + { + return adminInternalHostName; + } + + public static String getAdminExternalHostName() + { + return adminExternalHostName; + } + + public static String getAdminDNSZoneName() + { + return adminDNSZoneName; + } + + public static String getDnsLabelPrefix() + { + return dnsLabelPrefix; + } + + public static String getWlsDomainName() + { + return wlsDomainName; + } + + public static String getAzureResourceGroupRegion() + { + return azureResourceGroupRegion; + } + + public static String getGlobalResourceNameSuffix() + { + return globalResourceNameSuffix; + } + + public static String getAdminVMNamePrefix() + { + return adminVMNamePrefix; + } +} + diff --git a/weblogic-azure-vm/utilities/custom-hostname-verifier/src/main/java/WebLogicCustomHostNameVerifier.java b/weblogic-azure-vm/utilities/custom-hostname-verifier/src/main/java/WebLogicCustomHostNameVerifier.java new file mode 100644 index 000000000..8e8b68851 --- /dev/null +++ b/weblogic-azure-vm/utilities/custom-hostname-verifier/src/main/java/WebLogicCustomHostNameVerifier.java @@ -0,0 +1,68 @@ +package com.oracle.azure.weblogic.security.util; + +import com.oracle.azure.weblogic.HostNameValues; +import weblogic.security.utils.SSLCertUtility; + +public class WebLogicCustomHostNameVerifier implements weblogic.security.SSL.HostnameVerifier +{ + public boolean verify(String urlHostname, javax.net.ssl.SSLSession session) + { + String commonName = SSLCertUtility.getCommonName(session); + debug("commonName: "+commonName); + debug("urlHostname: "+urlHostname); + + String hostNameMatchStartString = new StringBuilder(HostNameValues.getDnsLabelPrefix().toLowerCase()).append("0").toString(); + String hostNameMatchEndString = new StringBuilder(HostNameValues.getWlsDomainName().toLowerCase()) + .append(".") + .append(HostNameValues.getAzureResourceGroupRegion().toLowerCase()) + .append(".") + .append(HostNameValues.azureVMExternalDomainName.toLowerCase()).toString(); + + String vmNameSubString = new StringBuilder(HostNameValues.getGlobalResourceNameSuffix()).toString(); + debug("vmNameSubString:"+vmNameSubString); + + if(commonName.equalsIgnoreCase(urlHostname)) + { + debug("urlhostname matching certificate common name"); + return true; + } + else + if(commonName.startsWith(HostNameValues.getAdminVMNamePrefix()) && urlHostname.contains(vmNameSubString)) + { + debug("matching with certificate common name and vmname"); + return true; + } + else + if(commonName.equalsIgnoreCase(HostNameValues.getAdminInternalHostName())) + { + debug("urlhostname matching certificate common name: "+HostNameValues.getAdminInternalHostName()+","+commonName); + return true; + } + else + if(commonName.equalsIgnoreCase(HostNameValues.getAdminExternalHostName())) + { + debug("urlhostname matching certificate common name: "+HostNameValues.getAdminExternalHostName()+","+commonName); + return true; + } + else + if(commonName.equalsIgnoreCase(HostNameValues.getAdminDNSZoneName())) + { + debug("adminDNSZoneName matching certificate common name: "+HostNameValues.getAdminDNSZoneName()+","+commonName); + return true; + } + else + if(commonName.startsWith(hostNameMatchStartString) && commonName.endsWith(hostNameMatchEndString)) + { + return true; + } + + return false; + } + + private void debug(String debugStatement) + { + if(HostNameValues.isDebugEnabled()) + System.out.println(debugStatement); + } +} + diff --git a/weblogic-azure-vm/utilities/custom-hostname-verifier/src/test/java/WebLogicCustomHostNameVerifierTest.java b/weblogic-azure-vm/utilities/custom-hostname-verifier/src/test/java/WebLogicCustomHostNameVerifierTest.java new file mode 100644 index 000000000..416888b44 --- /dev/null +++ b/weblogic-azure-vm/utilities/custom-hostname-verifier/src/test/java/WebLogicCustomHostNameVerifierTest.java @@ -0,0 +1,100 @@ +package com.oracle.azure.weblogic.security.test; + +import com.oracle.azure.weblogic.HostNameValues; +import com.oracle.azure.weblogic.security.util.WebLogicCustomHostNameVerifier; + + +public class WebLogicCustomHostNameVerifierTest +{ + private static String adminInternalHostName; + private static String adminExternalHostName; + private static String adminDNSZoneName; + private static String dnsLabelPrefix; + private static String wlsDomainName; + private static String azureResourceGroupRegion; + private static String debugFlag; + + public static void main(String args[]) + { + readArguments(args); + runTest(); + } + + private static void readArguments(String[] args) + { + if(args != null && args.length >= 6) + { + adminInternalHostName = args[0]; + adminExternalHostName = args[1]; + adminDNSZoneName = args[2]; + dnsLabelPrefix = args[3]; + wlsDomainName = args[4]; + azureResourceGroupRegion = args[5]; + debugFlag="false"; + + if(args.length > 6) + { + debugFlag=args[6]; + } + } + else + { + usage(); + } + } + + private static void runTest() + { + boolean fail=false; + + if(! HostNameValues.getAdminInternalHostName().equals(adminInternalHostName)) + { + System.out.println("Error !! adminInternalHostName not matching in HostNameValues.java: "+HostNameValues.getAdminInternalHostName()+","+adminInternalHostName); + fail=true; + } + + if(! HostNameValues.getAdminExternalHostName().equals(adminExternalHostName)) + { + System.out.println("Error !! adminExternalHostName not matching in HostNameValues.java "+HostNameValues.getAdminExternalHostName()+","+adminExternalHostName); + fail=true; + } + + if(! HostNameValues.getAdminDNSZoneName().equals(adminDNSZoneName)) + { + System.out.println("Error !! adminDNSZoneName not matching in HostNameValues.java "+HostNameValues.getAdminDNSZoneName()+","+adminDNSZoneName); + fail=true; + } + + if(! HostNameValues.getDnsLabelPrefix().equals(dnsLabelPrefix)) + { + System.out.println("Error !! dnsLabelPrefix not matching in HostNameValues.java "+HostNameValues.getDnsLabelPrefix()+","+dnsLabelPrefix); + fail=true; + } + + if(! HostNameValues.getWlsDomainName().equals(wlsDomainName)) + { + System.out.println("Error !! wlsDomainName not matching in HostNameValues.java "+HostNameValues.getWlsDomainName()+","+wlsDomainName); + fail=true; + } + + if(! HostNameValues.getAzureResourceGroupRegion().equals(azureResourceGroupRegion)) + { + System.out.println("Error !! azureResourceGroupRegion not matching in HostNameValues.java "+HostNameValues.getAzureResourceGroupRegion()+","+azureResourceGroupRegion); + fail=true; + } + + if(fail) + { + System.out.println("WebLogicCustomHostNameVerifierTest Failed !!"); + System.exit(1); + } + + System.out.println("WebLogicCustomHostNameVerifierTest Passed !!"); + } + + private static void usage() + { + System.out.println("Usage: java CustomHostNameVerifierGenerator []"); + System.exit(1); + } +} \ No newline at end of file