Clean-up, initial silent install framework

This commit is contained in:
Justin Donnelly
2020-10-11 05:17:58 +00:00
parent 05cf4b4277
commit dd01938790
11 changed files with 185 additions and 1213 deletions

View File

@@ -1,8 +1,16 @@
{
"registry.terraform.io/hashicorp/google": {
"hash": "h1:m4KVvG8BmApeUlLI2cL3P8sTY5yZZxrRE7PaHQQRa/M=",
"version": "3.41.0"
},
"registry.terraform.io/hashicorp/google-beta": {
"hash": "h1:zsIZIszrwu9B9TGiUMGUF3QrpOT6OxGrTIJIo+b8Re0=",
"version": "3.41.0"
},
"registry.terraform.io/hashicorp/null": {
"hash": "h1:ysHGBhBNkIiJLEpthB/IVCLpA1Qoncp3KbCTFGFZTO0=",
"version": "3.0.0"
},
"registry.terraform.io/hashicorp/random": {
"hash": "h1:nFL6uiwsQFLiP8QCr35sPfWe9LpXI3/c7gP9tYnih+k=",
"version": "2.3.0"

View File

@@ -1,367 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.43.0 (0)
-->
<!-- Title: %3 Pages: 1 -->
<svg width="2796pt" height="476pt"
viewBox="0.00 0.00 2796.37 476.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 472)">
<title>%3</title>
<polygon fill="white" stroke="transparent" points="-4,4 -4,-472 2792.37,-472 2792.37,4 -4,4"/>
<!-- [root] google_compute_disk.data (expand) -->
<g id="node1" class="node">
<title>[root] google_compute_disk.data (expand)</title>
<polygon fill="none" stroke="black" points="2046,-180 1842,-180 1842,-144 2046,-144 2046,-180"/>
<text text-anchor="middle" x="1944" y="-158.3" font-family="Times,serif" font-size="14.00">google_compute_disk.data</text>
</g>
<!-- [root] provider[&quot;registry.terraform.io/hashicorp/google&#45;beta&quot;] -->
<g id="node3" class="node">
<title>[root] provider[&quot;registry.terraform.io/hashicorp/google&#45;beta&quot;]</title>
<polygon fill="none" stroke="black" points="1589,-108 1212.29,-90 1589,-72 1965.71,-90 1589,-108"/>
<text text-anchor="middle" x="1589" y="-86.3" font-family="Times,serif" font-size="14.00">provider[&quot;registry.terraform.io/hashicorp/google&#45;beta&quot;]</text>
</g>
<!-- [root] google_compute_disk.data (expand)&#45;&gt;[root] provider[&quot;registry.terraform.io/hashicorp/google&#45;beta&quot;] -->
<g id="edge1" class="edge">
<title>[root] google_compute_disk.data (expand)&#45;&gt;[root] provider[&quot;registry.terraform.io/hashicorp/google&#45;beta&quot;]</title>
<path fill="none" stroke="black" d="M1857.61,-143.97C1799.91,-132.59 1724.6,-117.74 1668.4,-106.66"/>
<polygon fill="black" stroke="black" points="1668.98,-103.2 1658.5,-104.7 1667.63,-110.07 1668.98,-103.2"/>
</g>
<!-- [root] random_id.vm_suffix (expand) -->
<g id="node5" class="node">
<title>[root] random_id.vm_suffix (expand)</title>
<polygon fill="none" stroke="black" points="2376,-108 2212,-108 2212,-72 2376,-72 2376,-108"/>
<text text-anchor="middle" x="2294" y="-86.3" font-family="Times,serif" font-size="14.00">random_id.vm_suffix</text>
</g>
<!-- [root] google_compute_disk.data (expand)&#45;&gt;[root] random_id.vm_suffix (expand) -->
<g id="edge2" class="edge">
<title>[root] google_compute_disk.data (expand)&#45;&gt;[root] random_id.vm_suffix (expand)</title>
<path fill="none" stroke="black" d="M2029.17,-143.97C2081.46,-133.51 2148.43,-120.11 2201.94,-109.41"/>
<polygon fill="black" stroke="black" points="2202.65,-112.84 2211.77,-107.45 2201.28,-105.98 2202.65,-112.84"/>
</g>
<!-- [root] var.disk_type -->
<g id="node10" class="node">
<title>[root] var.disk_type</title>
<polygon fill="none" stroke="black" points="2088,-108 1984,-108 1984,-72 2094,-72 2094,-102 2088,-108"/>
<polyline fill="none" stroke="black" points="2088,-108 2088,-102 "/>
<polyline fill="none" stroke="black" points="2094,-102 2088,-102 "/>
<text text-anchor="middle" x="2039" y="-86.3" font-family="Times,serif" font-size="14.00">var.disk_type</text>
</g>
<!-- [root] google_compute_disk.data (expand)&#45;&gt;[root] var.disk_type -->
<g id="edge3" class="edge">
<title>[root] google_compute_disk.data (expand)&#45;&gt;[root] var.disk_type</title>
<path fill="none" stroke="black" d="M1967.48,-143.7C1979.56,-134.8 1994.45,-123.82 2007.52,-114.2"/>
<polygon fill="black" stroke="black" points="2009.81,-116.85 2015.79,-108.1 2005.66,-111.22 2009.81,-116.85"/>
</g>
<!-- [root] google_compute_instance.default (expand) -->
<g id="node2" class="node">
<title>[root] google_compute_instance.default (expand)</title>
<polygon fill="none" stroke="black" points="2152,-252 1898,-252 1898,-216 2152,-216 2152,-252"/>
<text text-anchor="middle" x="2025" y="-230.3" font-family="Times,serif" font-size="14.00">google_compute_instance.default</text>
</g>
<!-- [root] google_compute_instance.default (expand)&#45;&gt;[root] google_compute_disk.data (expand) -->
<g id="edge4" class="edge">
<title>[root] google_compute_instance.default (expand)&#45;&gt;[root] google_compute_disk.data (expand)</title>
<path fill="none" stroke="black" d="M2004.98,-215.7C1994.87,-206.97 1982.46,-196.24 1971.48,-186.75"/>
<polygon fill="black" stroke="black" points="1973.65,-183.99 1963.79,-180.1 1969.07,-189.29 1973.65,-183.99"/>
</g>
<!-- [root] var.image -->
<g id="node11" class="node">
<title>[root] var.image</title>
<polygon fill="none" stroke="black" points="2144,-180 2064,-180 2064,-144 2150,-144 2150,-174 2144,-180"/>
<polyline fill="none" stroke="black" points="2144,-180 2144,-174 "/>
<polyline fill="none" stroke="black" points="2150,-174 2144,-174 "/>
<text text-anchor="middle" x="2107" y="-158.3" font-family="Times,serif" font-size="14.00">var.image</text>
</g>
<!-- [root] google_compute_instance.default (expand)&#45;&gt;[root] var.image -->
<g id="edge5" class="edge">
<title>[root] google_compute_instance.default (expand)&#45;&gt;[root] var.image</title>
<path fill="none" stroke="black" d="M2045.27,-215.7C2055.5,-206.97 2068.06,-196.24 2079.18,-186.75"/>
<polygon fill="black" stroke="black" points="2081.63,-189.26 2086.96,-180.1 2077.09,-183.94 2081.63,-189.26"/>
</g>
<!-- [root] var.vm_type -->
<g id="node19" class="node">
<title>[root] var.vm_type</title>
<polygon fill="none" stroke="black" points="2265.5,-180 2168.5,-180 2168.5,-144 2271.5,-144 2271.5,-174 2265.5,-180"/>
<polyline fill="none" stroke="black" points="2265.5,-180 2265.5,-174 "/>
<polyline fill="none" stroke="black" points="2271.5,-174 2265.5,-174 "/>
<text text-anchor="middle" x="2220" y="-158.3" font-family="Times,serif" font-size="14.00">var.vm_type</text>
</g>
<!-- [root] google_compute_instance.default (expand)&#45;&gt;[root] var.vm_type -->
<g id="edge6" class="edge">
<title>[root] google_compute_instance.default (expand)&#45;&gt;[root] var.vm_type</title>
<path fill="none" stroke="black" d="M2072.7,-215.88C2099.95,-206.09 2134.3,-193.77 2162.97,-183.47"/>
<polygon fill="black" stroke="black" points="2164.22,-186.74 2172.45,-180.07 2161.86,-180.15 2164.22,-186.74"/>
</g>
<!-- [root] var.project_id -->
<g id="node14" class="node">
<title>[root] var.project_id</title>
<polygon fill="none" stroke="black" points="1520.5,-36 1413.5,-36 1413.5,0 1526.5,0 1526.5,-30 1520.5,-36"/>
<polyline fill="none" stroke="black" points="1520.5,-36 1520.5,-30 "/>
<polyline fill="none" stroke="black" points="1526.5,-30 1520.5,-30 "/>
<text text-anchor="middle" x="1470" y="-14.3" font-family="Times,serif" font-size="14.00">var.project_id</text>
</g>
<!-- [root] provider[&quot;registry.terraform.io/hashicorp/google&#45;beta&quot;]&#45;&gt;[root] var.project_id -->
<g id="edge21" class="edge">
<title>[root] provider[&quot;registry.terraform.io/hashicorp/google&#45;beta&quot;]&#45;&gt;[root] var.project_id</title>
<path fill="none" stroke="black" d="M1562,-73.12C1546,-63.7 1525.47,-51.63 1507.87,-41.28"/>
<polygon fill="black" stroke="black" points="1509.37,-38.1 1498.98,-36.04 1505.82,-44.13 1509.37,-38.1"/>
</g>
<!-- [root] var.region -->
<g id="node15" class="node">
<title>[root] var.region</title>
<polygon fill="none" stroke="black" points="1627.5,-36 1544.5,-36 1544.5,0 1633.5,0 1633.5,-30 1627.5,-36"/>
<polyline fill="none" stroke="black" points="1627.5,-36 1627.5,-30 "/>
<polyline fill="none" stroke="black" points="1633.5,-30 1627.5,-30 "/>
<text text-anchor="middle" x="1589" y="-14.3" font-family="Times,serif" font-size="14.00">var.region</text>
</g>
<!-- [root] provider[&quot;registry.terraform.io/hashicorp/google&#45;beta&quot;]&#45;&gt;[root] var.region -->
<g id="edge22" class="edge">
<title>[root] provider[&quot;registry.terraform.io/hashicorp/google&#45;beta&quot;]&#45;&gt;[root] var.region</title>
<path fill="none" stroke="black" d="M1589,-71.7C1589,-63.98 1589,-54.71 1589,-46.11"/>
<polygon fill="black" stroke="black" points="1592.5,-46.1 1589,-36.1 1585.5,-46.1 1592.5,-46.1"/>
</g>
<!-- [root] var.zone -->
<g id="node20" class="node">
<title>[root] var.zone</title>
<polygon fill="none" stroke="black" points="1722,-36 1652,-36 1652,0 1728,0 1728,-30 1722,-36"/>
<polyline fill="none" stroke="black" points="1722,-36 1722,-30 "/>
<polyline fill="none" stroke="black" points="1728,-30 1722,-30 "/>
<text text-anchor="middle" x="1690" y="-14.3" font-family="Times,serif" font-size="14.00">var.zone</text>
</g>
<!-- [root] provider[&quot;registry.terraform.io/hashicorp/google&#45;beta&quot;]&#45;&gt;[root] var.zone -->
<g id="edge23" class="edge">
<title>[root] provider[&quot;registry.terraform.io/hashicorp/google&#45;beta&quot;]&#45;&gt;[root] var.zone</title>
<path fill="none" stroke="black" d="M1612.17,-72.94C1625.41,-63.76 1642.24,-52.1 1656.86,-41.97"/>
<polygon fill="black" stroke="black" points="1658.95,-44.78 1665.17,-36.21 1654.96,-39.03 1658.95,-44.78"/>
</g>
<!-- [root] provider[&quot;registry.terraform.io/hashicorp/random&quot;] -->
<g id="node4" class="node">
<title>[root] provider[&quot;registry.terraform.io/hashicorp/random&quot;]</title>
<polygon fill="none" stroke="black" points="2294,-36 1943.6,-18 2294,0 2644.4,-18 2294,-36"/>
<text text-anchor="middle" x="2294" y="-14.3" font-family="Times,serif" font-size="14.00">provider[&quot;registry.terraform.io/hashicorp/random&quot;]</text>
</g>
<!-- [root] random_id.vm_suffix (expand)&#45;&gt;[root] provider[&quot;registry.terraform.io/hashicorp/random&quot;] -->
<g id="edge25" class="edge">
<title>[root] random_id.vm_suffix (expand)&#45;&gt;[root] provider[&quot;registry.terraform.io/hashicorp/random&quot;]</title>
<path fill="none" stroke="black" d="M2294,-71.7C2294,-63.98 2294,-54.71 2294,-46.11"/>
<polygon fill="black" stroke="black" points="2297.5,-46.1 2294,-36.1 2290.5,-46.1 2297.5,-46.1"/>
</g>
<!-- [root] var.additional_users -->
<g id="node6" class="node">
<title>[root] var.additional_users</title>
<polygon fill="none" stroke="black" points="154,-324 0,-324 0,-288 160,-288 160,-318 154,-324"/>
<polyline fill="none" stroke="black" points="154,-324 154,-318 "/>
<polyline fill="none" stroke="black" points="160,-318 154,-318 "/>
<text text-anchor="middle" x="80" y="-302.3" font-family="Times,serif" font-size="14.00">var.additional_users</text>
</g>
<!-- [root] var.availability_type -->
<g id="node7" class="node">
<title>[root] var.availability_type</title>
<polygon fill="none" stroke="black" points="332,-324 178,-324 178,-288 338,-288 338,-318 332,-324"/>
<polyline fill="none" stroke="black" points="332,-324 332,-318 "/>
<polyline fill="none" stroke="black" points="338,-318 332,-318 "/>
<text text-anchor="middle" x="258" y="-302.3" font-family="Times,serif" font-size="14.00">var.availability_type</text>
</g>
<!-- [root] var.backup_configuration -->
<g id="node8" class="node">
<title>[root] var.backup_configuration</title>
<polygon fill="none" stroke="black" points="545.5,-324 356.5,-324 356.5,-288 551.5,-288 551.5,-318 545.5,-324"/>
<polyline fill="none" stroke="black" points="545.5,-324 545.5,-318 "/>
<polyline fill="none" stroke="black" points="551.5,-318 545.5,-318 "/>
<text text-anchor="middle" x="454" y="-302.3" font-family="Times,serif" font-size="14.00">var.backup_configuration</text>
</g>
<!-- [root] var.database_version -->
<g id="node9" class="node">
<title>[root] var.database_version</title>
<polygon fill="none" stroke="black" points="730.5,-324 569.5,-324 569.5,-288 736.5,-288 736.5,-318 730.5,-324"/>
<polyline fill="none" stroke="black" points="730.5,-324 730.5,-318 "/>
<polyline fill="none" stroke="black" points="736.5,-318 730.5,-318 "/>
<text text-anchor="middle" x="653" y="-302.3" font-family="Times,serif" font-size="14.00">var.database_version</text>
</g>
<!-- [root] var.min_cpu -->
<g id="node12" class="node">
<title>[root] var.min_cpu</title>
<polygon fill="none" stroke="black" points="850,-324 754,-324 754,-288 856,-288 856,-318 850,-324"/>
<polyline fill="none" stroke="black" points="850,-324 850,-318 "/>
<polyline fill="none" stroke="black" points="856,-318 850,-318 "/>
<text text-anchor="middle" x="805" y="-302.3" font-family="Times,serif" font-size="14.00">var.min_cpu</text>
</g>
<!-- [root] var.private_network -->
<g id="node13" class="node">
<title>[root] var.private_network</title>
<polygon fill="none" stroke="black" points="1027.5,-324 874.5,-324 874.5,-288 1033.5,-288 1033.5,-318 1027.5,-324"/>
<polyline fill="none" stroke="black" points="1027.5,-324 1027.5,-318 "/>
<polyline fill="none" stroke="black" points="1033.5,-318 1027.5,-318 "/>
<text text-anchor="middle" x="954" y="-302.3" font-family="Times,serif" font-size="14.00">var.private_network</text>
</g>
<!-- [root] var.tier -->
<g id="node16" class="node">
<title>[root] var.tier</title>
<polygon fill="none" stroke="black" points="1114,-324 1052,-324 1052,-288 1120,-288 1120,-318 1114,-324"/>
<polyline fill="none" stroke="black" points="1114,-324 1114,-318 "/>
<polyline fill="none" stroke="black" points="1120,-318 1114,-318 "/>
<text text-anchor="middle" x="1086" y="-302.3" font-family="Times,serif" font-size="14.00">var.tier</text>
</g>
<!-- [root] var.user_name -->
<g id="node17" class="node">
<title>[root] var.user_name</title>
<polygon fill="none" stroke="black" points="1252,-324 1138,-324 1138,-288 1258,-288 1258,-318 1252,-324"/>
<polyline fill="none" stroke="black" points="1252,-324 1252,-318 "/>
<polyline fill="none" stroke="black" points="1258,-318 1252,-318 "/>
<text text-anchor="middle" x="1198" y="-302.3" font-family="Times,serif" font-size="14.00">var.user_name</text>
</g>
<!-- [root] var.user_password -->
<g id="node18" class="node">
<title>[root] var.user_password</title>
<polygon fill="none" stroke="black" points="1419.5,-324 1276.5,-324 1276.5,-288 1425.5,-288 1425.5,-318 1419.5,-324"/>
<polyline fill="none" stroke="black" points="1419.5,-324 1419.5,-318 "/>
<polyline fill="none" stroke="black" points="1425.5,-318 1419.5,-318 "/>
<text text-anchor="middle" x="1351" y="-302.3" font-family="Times,serif" font-size="14.00">var.user_password</text>
</g>
<!-- [root] meta.count&#45;boundary (EachMode fixup) -->
<g id="node21" class="node">
<title>[root] meta.count&#45;boundary (EachMode fixup)</title>
<ellipse fill="none" stroke="black" cx="1020" cy="-378" rx="222.86" ry="18"/>
<text text-anchor="middle" x="1020" y="-374.3" font-family="Times,serif" font-size="14.00">[root] meta.count&#45;boundary (EachMode fixup)</text>
</g>
<!-- [root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] var.additional_users -->
<g id="edge9" class="edge">
<title>[root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] var.additional_users</title>
<path fill="none" stroke="black" d="M812.53,-371.41C642.32,-365.1 395.02,-351.97 170.46,-324.09"/>
<polygon fill="black" stroke="black" points="170.82,-320.61 160.46,-322.84 169.94,-327.56 170.82,-320.61"/>
</g>
<!-- [root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] var.availability_type -->
<g id="edge10" class="edge">
<title>[root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] var.availability_type</title>
<path fill="none" stroke="black" d="M834.82,-367.92C701.95,-360.09 518.54,-346.62 348.6,-324.14"/>
<polygon fill="black" stroke="black" points="348.84,-320.64 338.47,-322.78 347.91,-327.57 348.84,-320.64"/>
</g>
<!-- [root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] var.backup_configuration -->
<g id="edge11" class="edge">
<title>[root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] var.backup_configuration</title>
<path fill="none" stroke="black" d="M888.44,-363.41C798.95,-353.79 677.6,-340.02 561.71,-324.21"/>
<polygon fill="black" stroke="black" points="561.97,-320.71 551.59,-322.82 561.02,-327.64 561.97,-320.71"/>
</g>
<!-- [root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] var.database_version -->
<g id="edge12" class="edge">
<title>[root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] var.database_version</title>
<path fill="none" stroke="black" d="M937.18,-361.2C880.62,-350.42 805.58,-336.1 746.82,-324.89"/>
<polygon fill="black" stroke="black" points="747.27,-321.42 736.79,-322.98 745.96,-328.29 747.27,-321.42"/>
</g>
<!-- [root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] var.min_cpu -->
<g id="edge13" class="edge">
<title>[root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] var.min_cpu</title>
<path fill="none" stroke="black" d="M969.05,-360.41C938.21,-350.37 898.7,-337.51 866.18,-326.92"/>
<polygon fill="black" stroke="black" points="866.92,-323.48 856.33,-323.71 864.76,-330.14 866.92,-323.48"/>
</g>
<!-- [root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] var.private_network -->
<g id="edge14" class="edge">
<title>[root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] var.private_network</title>
<path fill="none" stroke="black" d="M1003.69,-359.7C995.69,-351.22 985.93,-340.86 977.18,-331.58"/>
<polygon fill="black" stroke="black" points="979.53,-328.98 970.13,-324.1 974.44,-333.78 979.53,-328.98"/>
</g>
<!-- [root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] var.tier -->
<g id="edge15" class="edge">
<title>[root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] var.tier</title>
<path fill="none" stroke="black" d="M1036.31,-359.7C1044.31,-351.22 1054.07,-340.86 1062.82,-331.58"/>
<polygon fill="black" stroke="black" points="1065.56,-333.78 1069.87,-324.1 1060.47,-328.98 1065.56,-333.78"/>
</g>
<!-- [root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] var.user_name -->
<g id="edge16" class="edge">
<title>[root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] var.user_name</title>
<path fill="none" stroke="black" d="M1062.64,-360.23C1087.37,-350.51 1118.73,-338.17 1145.03,-327.83"/>
<polygon fill="black" stroke="black" points="1146.45,-331.03 1154.48,-324.12 1143.89,-324.52 1146.45,-331.03"/>
</g>
<!-- [root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] var.user_password -->
<g id="edge17" class="edge">
<title>[root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] var.user_password</title>
<path fill="none" stroke="black" d="M1095.52,-361.03C1146.43,-350.26 1213.66,-336.05 1266.37,-324.9"/>
<polygon fill="black" stroke="black" points="1267.31,-328.28 1276.37,-322.78 1265.86,-321.43 1267.31,-328.28"/>
</g>
<!-- [root] output.gce_external_ip (expand) -->
<g id="node22" class="node">
<title>[root] output.gce_external_ip (expand)</title>
<ellipse fill="none" stroke="black" cx="1632" cy="-306" rx="188.47" ry="18"/>
<text text-anchor="middle" x="1632" y="-302.3" font-family="Times,serif" font-size="14.00">[root] output.gce_external_ip (expand)</text>
</g>
<!-- [root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] output.gce_external_ip (expand) -->
<g id="edge7" class="edge">
<title>[root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] output.gce_external_ip (expand)</title>
<path fill="none" stroke="black" d="M1142.74,-362.96C1248.21,-350.9 1399.66,-333.58 1506.04,-321.41"/>
<polygon fill="black" stroke="black" points="1506.66,-324.86 1516.2,-320.25 1505.86,-317.9 1506.66,-324.86"/>
</g>
<!-- [root] output.gce_internal_ip (expand) -->
<g id="node23" class="node">
<title>[root] output.gce_internal_ip (expand)</title>
<ellipse fill="none" stroke="black" cx="2025" cy="-306" rx="186.57" ry="18"/>
<text text-anchor="middle" x="2025" y="-302.3" font-family="Times,serif" font-size="14.00">[root] output.gce_internal_ip (expand)</text>
</g>
<!-- [root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] output.gce_internal_ip (expand) -->
<g id="edge8" class="edge">
<title>[root] meta.count&#45;boundary (EachMode fixup)&#45;&gt;[root] output.gce_internal_ip (expand)</title>
<path fill="none" stroke="black" d="M1193.67,-366.69C1357.54,-356.7 1610.06,-340.66 1829,-324 1846.6,-322.66 1865.08,-321.17 1883.37,-319.64"/>
<polygon fill="black" stroke="black" points="1883.84,-323.11 1893.51,-318.79 1883.25,-316.14 1883.84,-323.11"/>
</g>
<!-- [root] output.gce_external_ip (expand)&#45;&gt;[root] google_compute_instance.default (expand) -->
<g id="edge18" class="edge">
<title>[root] output.gce_external_ip (expand)&#45;&gt;[root] google_compute_instance.default (expand)</title>
<path fill="none" stroke="black" d="M1716.79,-289.9C1776.12,-279.33 1855.8,-265.14 1919.27,-253.83"/>
<polygon fill="black" stroke="black" points="1920.09,-257.24 1929.32,-252.04 1918.86,-250.35 1920.09,-257.24"/>
</g>
<!-- [root] output.gce_internal_ip (expand)&#45;&gt;[root] google_compute_instance.default (expand) -->
<g id="edge19" class="edge">
<title>[root] output.gce_internal_ip (expand)&#45;&gt;[root] google_compute_instance.default (expand)</title>
<path fill="none" stroke="black" d="M2025,-287.7C2025,-279.98 2025,-270.71 2025,-262.11"/>
<polygon fill="black" stroke="black" points="2028.5,-262.1 2025,-252.1 2021.5,-262.1 2028.5,-262.1"/>
</g>
<!-- [root] provider[&quot;registry.terraform.io/hashicorp/google&#45;beta&quot;] (close) -->
<g id="node24" class="node">
<title>[root] provider[&quot;registry.terraform.io/hashicorp/google&#45;beta&quot;] (close)</title>
<ellipse fill="none" stroke="black" cx="2123" cy="-378" rx="328.44" ry="18"/>
<text text-anchor="middle" x="2123" y="-374.3" font-family="Times,serif" font-size="14.00">[root] provider[&quot;registry.terraform.io/hashicorp/google&#45;beta&quot;] (close)</text>
</g>
<!-- [root] provider[&quot;registry.terraform.io/hashicorp/google&#45;beta&quot;] (close)&#45;&gt;[root] google_compute_instance.default (expand) -->
<g id="edge20" class="edge">
<title>[root] provider[&quot;registry.terraform.io/hashicorp/google&#45;beta&quot;] (close)&#45;&gt;[root] google_compute_instance.default (expand)</title>
<path fill="none" stroke="black" d="M2177.3,-360.21C2194.32,-352.1 2211.2,-340.45 2221,-324 2229.19,-310.26 2230.73,-300.7 2221,-288 2210.23,-273.93 2177.68,-262.73 2142.13,-254.33"/>
<polygon fill="black" stroke="black" points="2142.56,-250.84 2132.04,-252.03 2141.01,-257.66 2142.56,-250.84"/>
</g>
<!-- [root] provider[&quot;registry.terraform.io/hashicorp/random&quot;] (close) -->
<g id="node25" class="node">
<title>[root] provider[&quot;registry.terraform.io/hashicorp/random&quot;] (close)</title>
<ellipse fill="none" stroke="black" cx="2479" cy="-234" rx="309.25" ry="18"/>
<text text-anchor="middle" x="2479" y="-230.3" font-family="Times,serif" font-size="14.00">[root] provider[&quot;registry.terraform.io/hashicorp/random&quot;] (close)</text>
</g>
<!-- [root] provider[&quot;registry.terraform.io/hashicorp/random&quot;] (close)&#45;&gt;[root] random_id.vm_suffix (expand) -->
<g id="edge24" class="edge">
<title>[root] provider[&quot;registry.terraform.io/hashicorp/random&quot;] (close)&#45;&gt;[root] random_id.vm_suffix (expand)</title>
<path fill="none" stroke="black" d="M2456.68,-215.87C2423.63,-190.5 2361.56,-142.85 2324.38,-114.32"/>
<polygon fill="black" stroke="black" points="2326.46,-111.5 2316.39,-108.19 2322.2,-117.05 2326.46,-111.5"/>
</g>
<!-- [root] root -->
<g id="node26" class="node">
<title>[root] root</title>
<ellipse fill="none" stroke="black" cx="2123" cy="-450" rx="58.49" ry="18"/>
<text text-anchor="middle" x="2123" y="-446.3" font-family="Times,serif" font-size="14.00">[root] root</text>
</g>
<!-- [root] root&#45;&gt;[root] meta.count&#45;boundary (EachMode fixup) -->
<g id="edge26" class="edge">
<title>[root] root&#45;&gt;[root] meta.count&#45;boundary (EachMode fixup)</title>
<path fill="none" stroke="black" d="M2066.4,-445.41C1907.84,-435.35 1454.23,-406.56 1199.37,-390.38"/>
<polygon fill="black" stroke="black" points="1199.46,-386.88 1189.26,-389.74 1199.02,-393.87 1199.46,-386.88"/>
</g>
<!-- [root] root&#45;&gt;[root] provider[&quot;registry.terraform.io/hashicorp/google&#45;beta&quot;] (close) -->
<g id="edge27" class="edge">
<title>[root] root&#45;&gt;[root] provider[&quot;registry.terraform.io/hashicorp/google&#45;beta&quot;] (close)</title>
<path fill="none" stroke="black" d="M2123,-431.7C2123,-423.98 2123,-414.71 2123,-406.11"/>
<polygon fill="black" stroke="black" points="2126.5,-406.1 2123,-396.1 2119.5,-406.1 2126.5,-406.1"/>
</g>
<!-- [root] root&#45;&gt;[root] provider[&quot;registry.terraform.io/hashicorp/random&quot;] (close) -->
<g id="edge28" class="edge">
<title>[root] root&#45;&gt;[root] provider[&quot;registry.terraform.io/hashicorp/random&quot;] (close)</title>
<path fill="none" stroke="black" d="M2181.47,-448.02C2267.64,-445.27 2422.58,-434.89 2460,-396 2494.22,-360.43 2490.47,-298.05 2484.72,-262.27"/>
<polygon fill="black" stroke="black" points="2488.1,-261.32 2482.91,-252.09 2481.21,-262.54 2488.1,-261.32"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -36,6 +36,10 @@ resource "google_compute_instance" "central" {
# hostname = "central-${random_id.vm_suffix.hex}"
# tags = ["foo", "bar"]
# timeouts {
# create = "60m"
# delete = "2h"
# }
boot_disk {
initialize_params {
@@ -67,5 +71,25 @@ resource "google_compute_instance" "central" {
email = "terraform@esoteric-parsec-243510.iam.gserviceaccount.com"
scopes = ["userinfo-email", "compute-rw", "storage-ro"]
}
}
resource "null_resource" "bootstrap" {
connection {
type = "winrm"
https = true
insecure = true
use_ntlm = true
user = var.user_name
password = var.user_password
host = google_compute_instance.central.name
timeout = "20m"
}
provisioner "remote-exec" {
inline = [
"powershell.exe -ExecutionPolicy Bypass -File E:\\deploy\\scripts\\win-nfs_client-install.ps1"
]
}
}

View File

@@ -1,29 +1,9 @@
#!/usr/bin/env pwsh
#
## Intended to be executed in a GitOps pipeline on the new GCE resource by remote-exec in TF
##
Enable-PSRemoting
winrm set 'winrm/config/client' '@{TrustedHosts="*"}'
## or as a startup script via Metadata key windows-startup-script-url
##
if(!(Get-LocalUser -Name qservice -ErrorAction Ignore)) {
$password = ConvertTo-SecureString -String 'Qlik1234!' -AsPlainText -Force
New-LocalUser `
-Name 'qservice' `
-Password $password `
-PasswordNeverExpires `
-UserMayNotChangePassword
}
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
New-Item -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation -Name AllowFreshCredentialsWhenNTLMOnly -Force
New-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation\AllowFreshCredentialsWhenNTLMOnly -Name 1 -Value * -PropertyType String
# if ($env:computername -ne 'central') {
# exit 0
# }
# Get-WmiObject -Class Win32_Volume -Filter "DriveType=5" | Set-WmiInstance -Arguments @{DriveLetter="Z:"}
Get-Disk |
Where-Object partitionstyle -eq 'raw' |
@@ -38,7 +18,7 @@ if (! (Test-Path E:\)) {
$deploy_path = "E:\deploy"
if (-Not (Test-Path $deploy_path)) {
if (! (Test-Path $deploy_path)) {
New-Item -ItemType Directory -Path $deploy_path
New-Item -ItemType Directory -Path $deploy_path\binaries
New-Item -ItemType Directory -Path $deploy_path\modules
@@ -46,34 +26,68 @@ if (-Not (Test-Path $deploy_path)) {
New-Item -ItemType Directory -Path $deploy_path\modules\ps
}
# Update these gcloud commands to be vars, allows portability
#
# CLOUDCLI_UPDATE
# OBJCLI_COPY
# gcloud components update -Force
gsutil -m cp gs://qliksense/Qlik_Sense* $deploy_path\binaries\
gcloud components update -Force
gsutil -m cp -r gs://qliksense/scripts $deploy_path\
gsutil -m cp -r gs://qliksense/modules 'C:\Program Files\WindowsPowerShell\Modules'
gsutil -m cp gs://qliksense/binaries/Qlik_Sense* $deploy_path\binaries\
# gsutil -m cp -r gs://qliksense/modules 'C:\Program Files\WindowsPowerShell\Modules'
Unblock-File -Path $deploy_path\binaries\Qlik_Sense_setup.exe
Unblock-File -Path $deploy_path\binaries\Qlik_Sense_update.exe
# Invoke-WebRequest -Uri https://github.com/PowerShell/PowerShell/releases/download/v7.0.3/PowerShell-7.0.3-win-x64.zip -OutFile $deploy_path\binaries\PowerShell-7.0.3-win-x64.zip
# iwr -Uri https://aka.ms/win32-x64-user-stable -Outfile ..\binaries\vscode_stable.exe
if ($env:computername -notlike "central-*") {
exit 0
}
if(!(Get-LocalUser -Name qservice -ErrorAction Ignore)) {
$password = ConvertTo-SecureString -String 'Qlik1234!' -AsPlainText -Force
New-LocalUser `
-Name 'qservice' `
-Password $password `
-PasswordNeverExpires `
-UserMayNotChangePassword
}
if(!(Get-LocalUser -Name qlikadmin -ErrorAction Ignore)) {
$password = ConvertTo-SecureString -String 'Qlik1234!' -AsPlainText -Force
New-LocalUser `
-Name 'qlikadmin' `
-Password $password `
-PasswordNeverExpires `
-UserMayNotChangePassword
}
Add-LocalGroupMember -Group "Administrators" -Member "qservice", "qlikadmin"
# WinRM Connects
New-Item -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation -Name AllowFreshCredentialsWhenNTLMOnly -Force
New-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation\AllowFreshCredentialsWhenNTLMOnly -Name 1 -Value * -PropertyType String
# Push-Location $deploy_path\modules\ps
Get-PackageProvider -Name NuGet -ForceBootstrap
# Below will also download and save the QlikResources requirements modules
# Save-Module -Path $deploy_path/modules/ps/ -Name QlikResources -RequiredVersion 1.9.2
# Save-Module -Path $deploy_path/modules/ps/ -Name GoogleCloud
Install-Module PSDesiredStateConfiguration -Force
Install-Module PSDscResources -Force
Install-Module QlikResources -Force
# HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
# New-ItemProperty -Path 'HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce' -Name 'Run' -Value '<insert_script_command_here>'
# $shortname = "$env:COMPUTERNAME".ToLower()
# $thumbprint = ( New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName $shortname -FriendlyName "WinRM HTTPS Listener" -NotAfter (Get-Date).AddYears(20) ).Thumbprint
Set-ExecutionPolicy Bypass -Scope Process -Force; E:\deploy\scripts\win-nfs_client-install.ps1
gcloud compute instances add-tags central-12d5 --tags=bootstrapped --zone europe-west1-d
# Testing Tools
# & $deploy_path\binaries\vscode_stable.exe /VERYSILENT /MERGETASKS=!runcode
# QSEoW FW Rule
Write-Host "<---- Create QSEoW FW Rule"
New-NetFirewallRule -DisplayName "Qlik Sense" -Direction Inbound -LocalPort 443, 4244,4242, 4432, 4444, 5355, 5353, 80, 4248, 3090, 4000, 5555, 5556, 4993, 4994 -Protocol TCP -Action Allow -ea Stop | Out-Null
# Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
# choco install git --no-progress
# Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1"
# Update-SessionEnvironment
# git clone https://gitlab+deploy-token-52544:YH-1SVsTrNmzj7AXz7oh@gitlab.com/ahaydon/cityclarity-psm.git ./CitiClarity
# Pop-Location
# Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
Set-GceInstance -Name $shortname -Zone europe-west1-d -AddTag "bootstrapped"
Set-GceInstance -Name $shortname -Zone europe-west1-d -RemoveMetadata "windows-startup-script-url"
Exit 0

View File

@@ -7,50 +7,52 @@ $configData = @{
$password = ConvertTo-SecureString -String 'Qlik1234!' -AsPlainText -Force
$SenseService = New-Object System.Management.Automation.PSCredential("$env:computername\qservice", $password)
$QlikAdmin = New-Object System.Management.Automation.PSCredential("$env:computername\qlik", $password)
$QlikAdmin = New-Object System.Management.Automation.PSCredential("$env:computername\qlikadmin", $password)
Configuration QlikConfig
{
Import-DscResource -ModuleName PSDesiredStateConfiguration, QlikResources
Import-DscResource -ModuleName QlikResources, PSDscResources
Node localhost
{
User QlikAdmin
{
UserName = $QlikAdmin.GetNetworkCredential().UserName
Password = $QlikAdmin
FullName = 'Qlik User'
PasswordChangeRequired = $false
PasswordNeverExpires = $true
Ensure = 'Present'
DependsOn = "[Windows]local"
}
# User QlikAdmin
# {
# UserName = $QlikAdmin.GetNetworkCredential().UserName
# Password = $QlikAdmin
# FullName = 'Qlik User'
# PasswordChangeRequired = $false
# PasswordNeverExpires = $true
# Ensure = 'Present'
# DependsOn = "[Windows]local"
# }
User SenseService
{
UserName = $SenseService.GetNetworkCredential().UserName
Password = $SenseService
FullName = 'Qlik Sense Service Account'
PasswordChangeNotAllowed = $true
PasswordChangeRequired = $false
PasswordNeverExpires = $true
Ensure = 'Present'
DependsOn = "[Windows]local"
}
# User SenseService
# {
# UserName = $SenseService.GetNetworkCredential().UserName
# Password = $SenseService
# FullName = 'Qlik Sense Service Account'
# PasswordChangeNotAllowed = $true
# PasswordChangeRequired = $false
# PasswordNeverExpires = $true
# Ensure = 'Present'
# DependsOn = "[Windows]local"
# }
Group Administrators
{
GroupName = 'Administrators'
MembersToInclude = $QlikAdmin.GetNetworkCredential().UserName, $SenseService.GetNetworkCredential().UserName
DependsOn = "[User]QlikAdmin", "[User]SenseService"
}
# Group Administrators
# {
# GroupName = 'Administrators'
# MembersToInclude = $QlikAdmin.GetNetworkCredential().UserName, $SenseService.GetNetworkCredential().UserName
# DependsOn = "[User]QlikAdmin", "[User]SenseService"
# }
QlikCentral CentralNode
{
SenseService = $SenseService
QlikAdmin = $QlikAdmin
ProductName = 'Qlik Sense June 2018'
SetupPath = 'C:\Install\Qlik_Sense_setup.exe'
ProductName = 'Qlik Sense September 2020 Patch 2'
SetupPath = 'E:\deploy\binaries\Qlik_Sense_setup.exe'
PatchPath = 'E:\deploy\binaries\Qlik_Sense_update.exe'
ClusterShareHost = ""
License = @{
Serial = '1234567890'
Control = '12345'
@@ -58,32 +60,37 @@ Configuration QlikConfig
Organization = 'Organization'
}
PSDscRunasCredential = $QlikAdmin
DependsOn = "[Group]Administrators"
DependsOn = "[MSFT_GroupResource]Administrators"
}
QlikVirtualProxy SAML
{
Prefix = "saml"
Description = "SAML"
SessionCookieHeaderName = "X-Qlik-Session-SAML"
LoadBalancingServerNodes = "name eq 'Central'"
AuthenticationMethod = "saml"
SamlMetadataIdp = (Get-Content -raw c:\install\idp-metadata.xml)
SamlHostUri = "https://$($env:computername)"
SamlEntityId = "https://$($env:computername)/saml"
SamlAttributeUserId = "uid"
SamlAttributeUserDirectory = "[SAML]"
SamlAttributeMapMandatory = @{
mail = 'email'
}
samlSlo = $true
SamlMetadataExportPath = "c:\install\saml_metadata_sp.xml"
Proxy = $env:computername
PSDscRunasCredential = $QlikAdmin
Ensure = "Present"
}
# QlikVirtualProxy SAML
# {
# Prefix = "saml"
# Description = "SAML"
# SessionCookieHeaderName = "X-Qlik-Session-SAML"
# LoadBalancingServerNodes = "name eq 'Central'"
# AuthenticationMethod = "saml"
# SamlMetadataIdp = (Get-Content -raw E:\deploy\idp-metadata.xml)
# SamlHostUri = "https://$($env:computername)"
# SamlEntityId = "https://$($env:computername)/saml"
# SamlAttributeUserId = "uid"
# SamlAttributeUserDirectory = "[SAML]"
# SamlAttributeMapMandatory = @{
# mail = 'email'
# }
# samlSlo = $true
# SamlMetadataExportPath = "E:\deploy\saml_metadata_sp.xml"
# Proxy = $env:computername
# PSDscRunasCredential = $QlikAdmin
# Ensure = "Present"
# }
}
}
QlikConfig -ConfigurationData $configData
Start-DscConfiguration -Path .\QlikConfig -Wait -Verbose -Force
if (! (Test-Path E:\deploy\scripts\QlikConfig)) {
New-Item -ItemType Directory -Path E:\deploy\scripts\QlikConfig
}
Start-DscConfiguration -Path E:\deploy\scripts\QlikConfig -Wait -Verbose -Force

View File

@@ -1,518 +0,0 @@
Configuration SenseSetup {
# Load required modules
Import-DscResource -ModuleName PSDesiredStateConfiguration, QlikResources #, xSmbShare, CitiClarity
# Configuration for all nodes
Node $AllNodes.NodeName {
LocalConfigurationManager
{
CertificateId = Get-PfxCertificate $Node.CertificateFile
ConfigurationMode = 'ApplyOnly'
RebootNodeIfNeeded = $false
}
# Ensure service account is in local Administrators group prior to install of Sense
$ServiceUsername = $Node.ServiceAccount.UserName
Script AdministratorsGroup {
TestScript = {
$IsMember = (Get-LocalGroupMember -Name Administrators).Name -contains $using:ServiceUsername
if (Test-Path "$env:ProgramFiles\Qlik\Sense") {
return (-Not $IsMember)
} else {
return $IsMember
}
}
SetScript = {
if (Test-Path "$env:ProgramFiles\Qlik\Sense") {
Remove-LocalGroupMember `
-Name 'Administrators' `
-Member $using:ServiceUsername
} else {
Add-LocalGroupMember `
-Name 'Administrators' `
-Member $using:ServiceUsername
}
}
GetScript = {
@{ Result = (Get-LocalGroupMember -Name Administrators) }
}
}
# Ensure 'High performance' power profile is active
Windows PowerPolicy {
PowerScheme = '8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c'
}
# Ensure pagefile size is set to 3GB for initial and max settings
PageFile Local {
InitialSize = 3072
MaximumSize = 3072
}
if ($Node.ProxyCert) {
CertificateImport Proxy {
Username = $Node.Node.ServiceAccount.Username
Permission = 'ReadAndExecute'
StoreLocation = 'LocalMachine\My'
FilePath = $Node.ProxyCert
Password = $CertificatePassword
}
}
}
# Node $AllNodes.Where{$_.Role -eq 'Scheduler'}.Nodename {
# $CentralNode = $AllNodes.Where{$_.Role -eq 'Central'}.NodeName
# # Skip kerberos if the installer doesn't exist
# if (Test-Path "\\$CentralNode\Clarity\Install\kfw-4.1-amd64.msi") {
# Package Kerberos {
# Name = 'MIT Kerberos for Windows (64-bit) 4.1.0'
# Path = "\\$CentralNode\Clarity\Install\kfw-4.1-amd64.msi"
# ProductId = '{AF6E168F-F6FE-4728-8F6E-E3E68F5C1FD3}'
# Credential = $Node.ServiceAccount
# Ensure = 'Present'
# }
# File krb5.ini {
# SourcePath = "\\$CentralNode\Clarity\Install\krb5.ini"
# DestinationPath = "$env:PROGRAMDATA\MIT\Kerberos5\krb5.ini"
# Type = 'File'
# Checksum = 'SHA-1'
# Ensure = 'Present'
# Credential = $Node.ServiceAccount
# DependsOn = '[Package]Kerberos'
# }
# File keytab {
# SourcePath = "\\$CentralNode\Clarity\Install\all_keytabs_prod"
# DestinationPath = "D:\all_keytabs_prod"
# Type = 'Directory'
# Checksum = 'SHA-1'
# MatchSource = $true
# Ensure = 'Present'
# Credential = $Node.ServiceAccount
# DependsOn = '[Package]Kerberos'
# }
# }
# # Skip Cloudera if installer doesn't exist
# if (Test-Path "\\$CentralNode\Clarity\Install\ClouderaImpalaODBC64.msi") {
# Package Cloudera {
# Name = 'Cloudera ODBC Driver for Impala'
# Path = "\\$CentralNode\Clarity\Install\ClouderaImpalaODBC64.msi"
# ProductId = '{111ADFD9-99CC-4695-8F48-44A5B397249D}'
# Credential = $Node.ServiceAccount
# Ensure = 'Present'
# }
# # Create ODBC DSN for Cloudera
# OdbcDsn Cloudera {
# DsnName = 'Impala PROD'
# DsnType = 'System'
# DriverName = 'Cloudera ODBC Driver for Impala'
# Platform = '64-Bit'
# Attribute = @{
# AllowHostNameCNMismatch = "0"
# AllowSelfSignedServerCert = "0"
# AsyncExecPollInterval = "10"
# AuthMech = "1"
# AutoReconnect = "1"
# CurrentSchemaRestrictedMetadata = "0"
# DefaultKeytabFile = "D:\all_keytabs_prod\pbgxsprd_dsccr001d01i1p.eur.nsroot.net.keytab"
# DelegateKrbCreds = "0"
# DelegationUID = ""
# DESCRIPTION = ""
# EnableSimulatedTransactions = "0"
# Host = "dsccr001d01i1p.eur.nsroot.net"
# KrbFQDN = "dsccr001d01i1p.eur.nsroot.net"
# KrbRealm = "EURUXPROD.DYN.NSROOT.NET"
# KrbServiceName = "impala"
# Port = "21050"
# RowsFetchedPerBlock = "10000"
# Schema = ""
# ServicePrincipalCanonicalization = "0"
# SocketTimeout = "30"
# SSL = "0"
# StringColumnLength = "32767"
# TrustedCerts = "C:\Program Files\Cloudera ODBC Driver for Impala\lib\cacerts.pem"
# TSaslTransportBufSize = "1000000"
# UID = "pbgxsprd/dsccr001d01i1p.eur.nsroot.net"
# UPNKeytabMappingFile = ""
# UseKeytab = "1"
# UseNativeQuery = "0"
# UseOnlySSPI = "0"
# UseSASL = "1"
# UseSQLUnicodeTypes = "0"
# UseSystemTrustStore = "0"
# LCaseSspKeyName = ""
# CheckCertRevocation = "1"
# }
# DependsOn = '[Package]Cloudera'
# }
# }
# }
# Configuration for Central node only
Node $AllNodes.Where{$_.Role -eq 'Central'}.NodeName {
NTFSAccess QlikProgramData {
Path = "$env:ProgramData\Qlik"
Permission = 'FullControl'
Username = $Node.ServiceAccount.Username
}
File QlikClusterRoot
{
Type = 'Directory'
DestinationPath = $ClusterLocalPath
Ensure = 'Present'
}
NTFSAccess QlikClusterRoot {
Path = $ClusterLocalPath
Permission = 'FullControl'
Username = $Node.ServiceAccount.Username
}
$ConfigurationData.NonNodeData.Shares.Cluster.Full.ForEach{
NTFSAccess "QlikClusterRoot-$($_)" {
Path = $ClusterLocalPath
Permission = 'FullControl'
Username = $_
}
}
# xSmbShare QlikClusterShare
# {
# Path = $ClusterLocalPath
# Name = 'Clarity'
# FullAccess = @($ConfigurationData.NonNodeData.Shares.Cluster.Full |?{$_}) +
# $Node.ServiceAccount.GetNetworkCredential().UserName
# Ensure = 'Present'
# DependsOn = '[File]QlikClusterRoot'
# }
# Install Sense as a Central node
QlikPackage Central
{
Name = $ConfigurationData.NonNodeData.Sense.ReleaseName
Setup = "$ClusterLocalPath\Install\Qlik_Sense_setup.exe"
Patch = "$(if(Test-Path "$ClusterLocalPath\Install\Qlik_Sense_update.exe"){"$ClusterLocalPath\Install\Qlik_Sense_update.exe"})"
ServiceCredential = $Node.ServiceAccount
RootDir = "\\$($Node.Hostname)\Clarity"
DbSuperUserPassword = $DbRepoUser
DbCredential = $DbRepoUser
CreateCluster = $true
InstallLocalDb = $true
ConfigureDbListener = $true
Hostname = $Node.Hostname
ConfigureLogging = $true
SetupLocalLoggingDb = $true
QLogsWriterPassword = $DbRepoUser
QLogsReaderPassword = $DbRepoUser
QLogsHostname = $Node.Hostname
QLogsPort = 4432
Ensure = 'Present'
PsDscRunasCredential = $Node.AdminAccount
DependsOn = '[NTFSAccess]QlikProgramData', '[xSmbShare]QlikClusterShare'
}
# Ensure QRD service is set for manual startup
# and is running as Sense service account
xService QRD {
Name = 'QlikSenseRepositoryDatabase'
StartupType = 'Manual'
State = 'Running'
Credential = $Node.ServiceAccount
DependsOn = '[QlikPackage]Central'
}
xService QRS {
Name = 'QlikSenseRepositoryService'
StartupType = 'Manual'
State = 'Running'
DependsOn = '[xService]QRD'
}
QlikConnect SenseCentral
{
Computername = $Node.Hostname
Username = $Node.AdminAccount.UserName
TrustAllCerts = $true
RetryDelay = 15
MaxRetries = 40
PsDscRunasCredential = $Node.AdminAccount
DependsOn = '[xService]QRS'
}
QlikLicense SiteLicense
{
Serial = $ConfigurationData.NonNodeData.Sense.License.Serial
Control = $ConfigurationData.NonNodeData.Sense.License.Control
Name = $ConfigurationData.NonNodeData.Sense.License.Name
Organization = $ConfigurationData.NonNodeData.Sense.License.Organization
Lef = $ConfigurationData.NonNodeData.Sense.License.Lef
Ensure = "Present"
PsDscRunasCredential = $Node.AdminAccount
DependsOn = "[QlikConnect]SenseCentral"
}
# Ensure accounts listed in the environment data file are RootAdmin
$ConfigurationData.NonNodeData.Sense.RootAdmin.foreach{
QlikUser $_ {
UserId = $_.Substring($_.IndexOf('\') + 1)
UserDirectory = $_.Substring(0, $_.IndexOf('\'))
Roles = 'RootAdmin'
Ensure = 'Present'
PsDscRunasCredential = $Node.AdminAccount
DependsOn = '[QlikLicense]SiteLicense'
}
}
SenseCertificate Windows {
MachineName = $Node.NodeName
Password = $certPassword
IncludeSecretKey = $true
ExportFormat = 'Windows'
PsDscRunasCredential = $Node.AdminAccount
DependsOn = '[QlikLicense]SiteLicense'
}
SenseCertificate Pem {
MachineName = $Node.NodeName
Password = $certPassword
IncludeSecretKey = $true
ExportFormat = 'Pem'
PsDscRunasCredential = $Node.AdminAccount
DependsOn = '[QlikLicense]SiteLicense'
}
# Copy Sense server certificate to PostgreSQL directory
File Postgres_cert {
SourcePath = "$env:PROGRAMDATA\Qlik\Sense\Repository\Exported Certificates\.Local Certificates\server.pem"
DestinationPath = "$env:PROGRAMDATA\Qlik\Sense\Repository\PostgreSQL\9.6\server.pem"
Type = 'File'
Ensure = 'Present'
DependsOn = '[xService]QRS'
}
# Copy Sense server key to PostgreSQL directory
File Postgres_key {
SourcePath = "$env:PROGRAMDATA\Qlik\Sense\Repository\Exported Certificates\.Local Certificates\server_key.pem"
DestinationPath = "$env:PROGRAMDATA\Qlik\Sense\Repository\PostgreSQL\9.6\server_key.pem"
Type = 'File'
Ensure = 'Present'
DependsOn = '[xService]QRS'
}
# Ensure SSL settings are configured in postgresql.conf
# and max connections is set to node count * 100
# Ensure Postgres access control is configured for SSL only
Postgres Local {
SSL = $true
SSLCiphers = 'DEFAULT:!LOW:!EXP:!eNULL:!aNULL:!MD5:!RC2:!RC4:!DES:@STRENGTH'
CertFile = 'server.pem'
KeyFile = 'server_key.pem'
MaxConnections = $AllNodes.Count * 100
HostAccess = @(
'hostssl all all all md5',
'host all all all md5'
)
IdleTransactionTimeout = '5min'
Credential = $DbSuperUser
DependsOn = '[File]Postgres_cert', '[File]Postgres_key'
}
}
# Configuration for Rim nodes only (not Central)
Node $AllNodes.Where{$_.Role -ne 'Central'}.NodeName {
$CentralNode = $AllNodes.Where{$_.Role -eq 'Central'}.Hostname
# Copy setup file to local disk
File SenseSetup {
SourcePath = "\\$CentralNode\Clarity\Install\Qlik_Sense_setup.exe"
DestinationPath = "C:\Install\Qlik_Sense_setup.exe"
Type = 'File'
Checksum = 'SHA-1'
Ensure = 'Present'
Credential = $Node.ServiceAccount
}
# If patch file exists copy it to local disk
if (Test-Path "$ClusterLocalPath\Install\Qlik_Sense_update.exe") {
$SenseUpdate = "C:\Install\Qlik_Sense_update.exe"
File SenseUpdate {
SourcePath = "\\$CentralNode\Clarity\Install\Qlik_Sense_update.exe"
DestinationPath = $SenseUpdate
Type = 'File'
Checksum = 'SHA-1'
Ensure = 'Present'
Credential = $Node.ServiceAccount
}
}
# Pause execution if central node is not ready
WaitForSense $CentralNode {
ComputerName = $CentralNode
RetryDelay = 60
MaxRetries = 30
SkipVerify = $true
PsDscRunasCredential = $Node.AdminAccount
}
# Install Qlik Sense as Rim node
# and join existing cluster (including registering with Central)
QlikRimNode $Node.NodeName {
SenseService = $Node.ServiceAccount
ProductName = $ConfigurationData.NonNodeData.Sense.ReleaseName
SetupPath = 'C:\Install\Qlik_Sense_setup.exe'
PatchPath = $SenseUpdate
Hostname = $Node.Hostname
Name = $Node.Name
CentralNode = $CentralNode
DbCredential = $DbRepoUser
Engine = ($Node.Role -match 'Engine' -or $Node.Role -eq 'Scheduler')
Printing = ($Node.Role -match 'Engine')
Proxy = ($Node.Role -match 'Proxy')
Scheduler = ($Node.Role -eq 'Scheduler')
ManageServices = $false
ManageFirewall = $false
PsDscRunasCredential = $Node.AdminAccount
DependsOn = @("[WaitForSense]$CentralNode", '[File]SenseSetup') + $(if($SenseUpdate){'[File]SenseUpdate'})
}
}
# Configuration for all nodes
Node $AllNodes.NodeName {
# Ensure Sense program data is shared as Sense
# with access levels defined in environment data file
xSmbShare Sense {
Path = "$env:ProgramData\Qlik\Sense"
Name = 'Sense'
FullAccess = @($ConfigurationData.NonNodeData.Shares.Sense.Full |?{$_}) +
$Node.ServiceAccount.GetNetworkCredential().UserName
ReadAccess = $ConfigurationData.NonNodeData.Shares.Sense.Read
Ensure = 'Present'
DependsOn = if($Node.Role -eq 'Central'){'[Postgres]Local'}else{"[QlikRimNode]$($Node.Nodename)"}
}
Group SenseServiceUsers {
GroupName = 'Qlik Sense Service Users'
MembersToInclude = $Node.ServiceAccount.UserName
PsDscRunAsCredential = $Node.AdminAccount
DependsOn = '[xSmbShare]Sense'
}
Group PerfMonUsers {
GroupName = 'Performance Monitor Users'
MembersToInclude = $Node.ServiceAccount.UserName
PsDscRunAsCredential = $Node.AdminAccount
DependsOn = '[xSmbShare]Sense'
}
# Delete the examples directory as required by security audit
File Examples {
DestinationPath = 'C:\ProgramData\Qlik\Examples'
Type = 'Directory'
Ensure = 'Absent'
Force = $true
Credential = $Node.ServiceAccount
DependsOn = '[xSmbShare]Sense'
}
# Remove HTTP server header for DotNot web servers (Sense Proxy)
HTTP Server {
DisableServerHeader = 2
DependsOn = '[xSmbShare]Sense'
}
# Ensure all Sense services are configured for manual startup
@(
'QlikSenseEngineService',
'QlikSensePrintingService',
'QlikSenseProxyService',
'QlikSenseRepositoryService',
'QlikSenseSchedulerService',
'QlikSenseServiceDispatcher'
).ForEach{
xService $_ {
Name = $_
StartupType = 'Manual'
State = 'Running'
DependsOn = '[Group]SenseServiceUsers', '[Group]PerfMonUsers'
}
}
# Ensure Qlik logging service is stopped and disabled
xService QlikLogging {
Name = 'QlikLoggingService'
StartupType = 'Disabled'
State = 'Stopped'
DependsOn = '[xService]QlikSenseRepositoryService'
}
# Wait for Sense services to be ready by checking service status on central node
WaitForSense Repository {
ComputerName = $AllNodes.Where{$_.Role -eq 'Central'}.Hostname
Node = $Node.Hostname
MaxRetries = 20
RetryDelay = 30
PsDscRunasCredential = $Node.AdminAccount
DependsOn = '[xService]QlikSenseRepositoryService'
}
if($Node.ProxyCert) {
$Thumbprint = (Get-PfxData -FilePath $Node.ProxyCert).EndEntityCertificates.ThumbPrint
}
# Ensure SSL certificate thumbprint is configured for Proxy service
QlikProxy Local {
Node = $Node.Hostname
SslBrowserCertificateThumbprint = $Thumbprint
PsDscRunAsCredential = $Node.AdminAccount
DependsOn = '[WaitForSense]Repository'
}
# Ensure default virtual proxies are configured to load balance to engine nodes
# and host names defined in environment data file are in whitelist
QlikVirtualProxy Default {
Description = "$($Node.Name) Proxy (Default)"
Prefix = '/'
SessionCookieHeaderName = 'X-Qlik-Session'
LoadBalancingServerNodes = "engineEnabled eq true and schedulerEnabled eq false"
WebSocketCrossOriginWhitelist = $ConfigurationData.NonNodeData.Sense.HostWhitelist
AdditionalResponseHeaders = @"
X-XSS-Protection: 1
X-Frame-Options: deny
Content-Security-Policy: frame-ancestors 'none'
Strict-Transport-Security: max-age=86400; includeSubDomains
X-Content-Type-Options: nosniff
"@
Ensure = 'Present'
PsDscRunasCredential = $Node.AdminAccount
DependsOn = '[WaitForSense]Repository'
}
# Ensure QRS connection string is configured for SSL
# and is set to use TLS 1.2 only
# SenseRepository Postgres {
# SSLMode = 'Require'
# TLSProtocol = '1.3'
# PostgresCommandTimeout = 0
# DependsOn = '[WaitForSense]Repository'
# }
# $CentralNode = $AllNodes.Where{$_.Role -eq 'Central'}.NodeName
# $NodeSetup = @(Get-ChildItem "$ClusterLocalPath\Install\node-*.msi")[0].Name
# # Upgrade the version of node js used by the Sense service dispatcher
# if ($NodeSetup) {
# Package NodeJS {
# Name = 'Node.js'
# Path = "\\$CentralNode\Clarity\Install\$NodeSetup"
# ProductId = '{A6606125-61E2-43C3-BFCF-0E571EC56656}'
# Arguments = 'INSTALLDIR="C:\Program Files\Qlik\Sense\ServiceDispatcher\Node" REBOOT=ReallySuppress /norestart'
# Credential = $Node.ServiceAccount
# Ensure = 'Present'
# DependsOn = '[QlikProxy]Local', '[QlikVirtualProxy]Default'
# }
# }
}
}

View File

@@ -1,94 +0,0 @@
@{
AllNodes = @(
@{
NodeName = 'sense0'
Hostname = 'sense0'
Name = 'Central'
Role = "Central"
ConcurrentTasks = 10
},
@{
NodeName = 'sense1'
Hostname = 'sense1'
Name = 'Scheduler 1'
Role = "Scheduler"
},
@{
NodeName = 'sense2'
Hostname = 'sense2'
Name = 'Scheduler 2'
Role = "Scheduler"
},
@{
NodeName = 'sense3'
Hostname = 'sense3'
Name = 'Engine 1'
Role = "Engine"
},
@{
NodeName = 'sense4'
Hostname = 'sense4'
Name = 'Engine 2'
Role = "Engine"
},
@{
NodeName = 'sense5'
Hostname = 'sense5'
Name = 'Engine 3'
Role = "Engine"
},
@{
NodeName = 'sense6'
Hostname = 'sense6'
Name = 'Proxy 1'
Role = "Proxy"
},
@{
NodeName = 'sense7'
Hostname = 'sense7'
Name = 'Proxy 2'
Role = "Proxy"
}
)
NonNodeData = @{
Thumprint = ''
Sense = @{
ReleaseName = 'Qlik Sense November 2017'
License = @{
Serial = '9999000000001292'
Control = '16902'
Name = 'Qlik'
Organization = 'Qlik'
Lef = @"
9999000000001292
PURPOSE;2019 Internal Sense Token Key;;
PRODUCTLEVEL;50;;2020-01-31
TOKENS;100;;
OVERAGE;NO;;
TIMELIMIT;;;2020-01-31
Z8D9-SZYD-J5RR-D86G-2M4L
"@
}
RootAdmin = @(
)
HostWhiteList = 'sense0'
}
Shares = @{
Cluster = @{
Full = @(
'qlik'
)
Read = @()
}
Sense = @{
Full = @(
'qlik'
)
Read = @(
'guest'
)
}
}
}
}

View File

@@ -1,122 +0,0 @@
Configuration Main {
Param (
[string]$SenseSetupUri = "https://da3hntz84uekx.cloudfront.net/QlikSense/11.24/0/_MSI/Qlik_Sense_setup.exe",
[string]$SenseUpdateUri = "https://da3hntz84uekx.cloudfront.net/QlikSense/11.24/1/_MSI/Qlik_Sense_update.exe",
[string]$DownloadPath = $env:temp,
[PSCredential]$SenseService,
[Parameter(ParameterSetName = "Central")]
[PSCredential]$QlikAdmin,
[string]$ClusterShareHost,
[string]$Hostname,
[Parameter(ParameterSetName = "Central")]
$LicenseSerial = $ConfigurationData.NonNodeData.License.Serial,
[Parameter(ParameterSetName = "Central")]
$LicenseControl = $ConfigurationData.NonNodeData.License.Control,
[Parameter(ParameterSetName = "Central")]
$LicenseOrg = $ConfigurationData.NonNodeData.License.Organization,
[Parameter(ParameterSetName = "Central")]
$LicenseName = $ConfigurationData.NonNodeData.License.Name,
[Parameter(ParameterSetName = "Central", Mandatory = $false)]
$LicenseLef = $ConfigurationData.NonNodeData.License.Lef,
[Parameter(ParameterSetName = "RimNode")]
$CentralNode,
[Parameter(ParameterSetName = "RimNode")]
[ValidateSet("Proxy", "Engine", "ProxyEngine", "Scheduler", "All")]
$NodeType = "All"
)
Import-DscResource -ModuleName PSDesiredStateConfiguration, xPSDesiredStateConfiguration, QlikResources
Node localhost
{
User QlikAdmin
{
UserName = $QlikAdmin.GetNetworkCredential().UserName
Password = $QlikAdmin
FullName = 'QlikAdmin'
PasswordChangeRequired = $false
PasswordNeverExpires = $true
Ensure = 'Present'
}
User SenseService
{
UserName = $SenseService.GetNetworkCredential().UserName
Password = $SenseService
FullName = 'Qlik Sense Service Account'
PasswordChangeNotAllowed = $true
PasswordChangeRequired = $false
PasswordNeverExpires = $true
Ensure = 'Present'
}
Group Administrators
{
GroupName = 'Administrators'
MembersToInclude = $QlikAdmin.GetNetworkCredential().UserName, $SenseService.GetNetworkCredential().UserName
}
File DownloadPath
{
Type = 'Directory'
DestinationPath = Join-Path -Path $DownloadPath -ChildPath $Name
Ensure = 'Present'
}
$SenseSetupPath = Join-Path -Path $DownloadPath -ChildPath $SenseSetupUri.Substring($SenseSetupUri.LastIndexOf('/') + 1)
xRemoteFile SenseSetup
{
DestinationPath = $SenseSetupPath
Uri = $SenseSetupUri
MatchSource = $false
}
$SenseUpdatePath = Join-Path -Path $DownloadPath -ChildPath $SenseUpdateUri.Substring($SenseUpdateUri.LastIndexOf('/') + 1)
xRemoteFile SenseUpdate
{
DestinationPath = $SenseUpdatePath
Uri = $SenseUpdateUri
MatchSource = $false
}
if ($PsCmdlet.ParameterSetName -EQ 'Central') {
QlikCentral CentralNode
{
SenseService = $SenseService
QlikAdmin = $QlikAdmin
ProductName = "Qlik Sense November 2017 Patch 1"
SetupPath = $SenseSetupPath
PatchPath = $SenseUpdatePath
Hostname = $Hostname
ClusterShareHost = $ClusterShareHost
License = @{
Serial = $LicenseSerial
Control = $LicenseControl
Name = $LicenseName
Organization = $LicenseOrg
Lef = $LicenseLef
}
PSDscRunasCredential = $QlikAdmin
}
}
else {
QlikRimNode $Hostname
{
SenseService = $SenseService
QlikAdmin = $QlikAdmin
ProductName = "Qlik Sense November 2017 Patch 1"
SetupPath = $SenseSetupPath
PatchPath = $SenseUpdatePath
Hostname = $Hostname
CentralNode = $CentralNode
Proxy = (@('Proxy', 'ProxyEngine', 'All') -contains $NodeType)
Engine = (@('Engine', 'ProxyEngine', 'Scheduler', 'All') -contains $NodeType)
Printing = (@('Engine', 'ProxyEngine', 'All') -contains $NodeType)
Scheduler = (@('Scheduler', 'All') -contains $NodeType)
PSDscRunasCredential = $QlikAdmin
}
}
}
}

View File

@@ -1,16 +0,0 @@
# Push-Location ~/Downloads
# Invoke-WebRequest -Uri https://da3hntz84uekx.cloudfront.net/QlikSense/13.95/0/_MSI/Qlik_Sense_setup.exe -OutFile .\binaries\Qlik_Sense_setup.exe
# Invoke-WebRequest -Uri https://da3hntz84uekx.cloudfront.net/QlikSense/13.95/1/_MSI/Qlik_Sense_update.exe -OutFile .\binaries\Qlik_Sense_update.exe
Get-PackageProvider -Name NuGet -ForceBootstrap
Install-Module -Name GoogleCloud -Force
Install-Module -Name xPSDesiredStateConfiguration -Force
Install-Module -Name xNetworking -Force
Install-Module -Name xSmbShare -Force
Install-Module -Name Qlik-Cli -Force
Install-Module -Name QlikResources -Force
# $bucket = "qliksense"
# New-GcsObject -Bucket $bucket -Folder ".\binaries" -ObjectNamePrefix "binaries" -Force
# Pop-Location

View File

@@ -0,0 +1,24 @@
<?xml version="1.0"?>
<SharedPersistenceConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<DbUserName>qliksenserepository</DbUserName>
<DbUserPassword>Qlik1234!</DbUserPassword>
<DbHost>10.54.242.2</DbHost>
<DbPort>5432</DbPort>
<RootDir>\\10.236.6.170\qlikshare</RootDir>
<StaticContentRootDir>\\10.236.6.170\qlikshare\StaticContent</StaticContentRootDir>
<ArchivedLogsDir>\\10.236.6.170\qlikshare\ArchivedLogs</ArchivedLogsDir>
<AppsDir>\\10.236.6.170\qlikshare\Apps</AppsDir>
<CreateCluster>true</CreateCluster>
<InstallLocalDb>false</InstallLocalDb>
<ConfigureDbListener>false</ConfigureDbListener>
<ListenAddresses>*</ListenAddresses>
<IpRange>0.0.0.0/0,::/0</IpRange>
<MaxConnections>100</MaxConnections>
<!-- <JoinCluster>true</JoinCluster> -->
<ConfigureLogging>false</ConfigureLogging>
<SetupLocalLoggingDb>false</SetupLocalLoggingDb>
<QLogsWriterPassword>Qlik1234!</QLogsWriterPassword>
<QLogsReaderPassword>Qlik1234!</QLogsReaderPassword>
<QLogsHostname>10.54.242.2</QLogsHostname>
<QLogsPort>5432</QLogsPort>
</SharedPersistenceConfiguration>

View File

@@ -1,6 +1,13 @@
#!/usr/bin/env pwsh
# Install NFS Client on Windows via PS
#
# Wait for bootstrap.ps1 to finish before proceeding.
# $bootScript = "bootstrap.ps1"
# Wait-Process -Name $bootScript -ErrorAction SilentlyContinue -Timeout 1200
# Enable NFS Client, set Anon user to UID:GID 0 == root. Restart service.
Write-Host -Message "<---- Installing NFS"
Install-WindowsFeature -Name NFS-Client
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\ClientForNFS\CurrentVersion\Default" `
-Name "AnonymousUid" -Value "0" -PropertyType DWORD
@@ -8,3 +15,8 @@ New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\ClientForNFS\CurrentVersion\Def
-Name "AnonymousGid" -Value "0" -PropertyType DWORD
nfsadmin client stop
nfsadmin client start
# & E:\deploy\binaries\Qlik_Sense_setup.exe -s -l E:\deploy\deploy.log spc="E:\deploy\scripts\spc.xml" installdir="E:\deploy\Qlik" userwithdomain="central-b445\qservice" userpassword="Qlik1234!" dbpassword="Qlik1234!" accepteula=1 skipvalidation=1 bundleinstall=1 skipdbconfig=1
Write-Host "<---- Installing QSEoW"
Invoke-Command -ScriptBlock {Start-Process -FilePath "E:\deploy\binaries\Qlik_Sense_setup.exe" -ArgumentList "-s -log E:\deploy\deploy.log accepteula=1 installdir=E:\deploy\Qlik dbpassword=Qlik1234! hostname=$($env:computername) userwithdomain=$($env:computername)\qservice password=Qlik1234! bundleinstall=dashboard,visualization spc=E:\deploy\scripts\spc.xml" -Wait -PassThru} | Out-Null