Files
@ 2935e65f230e
Branch filter:
Location: majic-ansible-roles/docs/usage.rst - annotation
2935e65f230e
59.3 KiB
text/prs.fallenstein.rst
MAR-18: Added more information on how the PHP apps are executed to the usage instructions (and where the files are served from). Added usage instructions for deploying a WSGI appliction (Django Wiki in this case).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 | c377c1d24d7c c377c1d24d7c c377c1d24d7c c377c1d24d7c c377c1d24d7c c482961647bf c482961647bf c482961647bf c482961647bf dbd4c92f4e4f dbd4c92f4e4f c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf 5b1624335e63 c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf c482961647bf 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 4acb74ace813 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a dbd4c92f4e4f 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a dbd4c92f4e4f 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a dbd4c92f4e4f 0969ee81219a 0969ee81219a 0969ee81219a 0969ee81219a dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f dbd4c92f4e4f e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 e2c7276ecff7 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 cd11d6826378 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 7a01af815f91 5b1624335e63 7a01af815f91 7a01af815f91 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 80c77d68b540 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 2935e65f230e 2935e65f230e 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 2935e65f230e 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 5b1624335e63 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e 2935e65f230e | .. _usage:
Usage
=====
Majic Ansible Roles are targeted at sysadmins who wish to deploy services for
their own, small-scale use. This chapter gives a simple tutorial-like set of
instructions for using all of the roles available.
.. contents:: :local:
Overview
--------
There is a number of different roles that can prove useful for setting-up a
small infrastructure of your own.
Some roles are suited for one-off operations during installation, like the
``preseed`` and ``bootstrap``, while some are better suited for periodic runs
for maintaining the users and integrity of the system.
By the end of the instructions you will have the following:
* Ansible server, used for configuring the remaining servers.
* Communications server, providing the LDAP, mail, and XMPP services.
* Web server, providing the web services.
Pre-requisites
--------------
For the set-up outlined in this usage guide you'll need the following:
* One server where Ansible will be installed at. Debian Jessie will be installed
on top of this server. The server will be set-up manually (this is currently
out of scope for the *Majic Ansible Roles* automated set-up).
* Two servers where the services will be set-up. Both servers must be able to
communicate over network with each-other, the Ansible servers, and with
Internet. Debian Jessie will be installed on top of this server as part of the
usage instructions.
* Debian Jessie network install CD.
* All servers should be on the same network.
* IP addresses for all three servers should be known.
* Netmask for all three servers should be known.
* Gateway for all three servers should be known.
In case of the three servers above, it might be safest to have three VMs
available and handy.
Usage instructions assume the following:
* Domain used for all three servers is ``example.com``. If you wish to use a
different domain, adjust the instructions accordingly.
* Server hostnames are ``ansible``, ``comms``, and ``www`` (for Ansible server,
communications server, and web server respectively).
Installing the OS on Ansible server
-----------------------------------
Start-off by installing the operating system on the Ansible server:
1. Fire-up the ``ansible`` server, and boot from the network installation CD.
2. Select the **Install** option.
3. Pick **English** as language.
4. Pick the country you are living in (or whatever else you want).
5. Pick the **en_US.UTF-8** locale.
6. Pick the **American English** keymap.
7. Configure the network if necessary.
8. Set the hostname to ``ansible``.
9. Set the domain to ``example.com``.
10. Set the root password.
11. Create a new user. For simplicity, call the user **Ansible user**, with
username **ansible**.
12. Set-up partitioning in any way you want. You can go for **Guided - use
entire disk** if you want to keep it simple and are just testing things.
13. Wait until the base system has been installed.
14. Pick whatever Debian archive mirror is closest to you.
15. If you have an HTTP proxy, provide its URL.
16. Pick if you want to participate in package survey or not.
17. Make sure that at least the **standard system utilities** and **SSH server**
options are selected on task selection screen.
18. Wait for packages to be installed.
19. Install the GRUB boot loader on MBR.
20. Finalise the server install, and remove the installation media from server.
Installing required packages
----------------------------
With the operating system installed, it is necessary to install a couple of
packages, and to prepare the environment a bit on the Ansible server:
1. Install the necessary system packages (using the ``root`` account)::
apt-get install -y virtualenv virtualenvwrapper git python-pip python-dev
2. Set-up the virtual environment (using the ``ansible`` account)::
mkdir ~/mysite/
mkvirtualenv -a ~/mysite/ mysite
pip install ansible
Cloning the *Majic Ansible Roles*
---------------------------------
With most of the software pieces in place, the only missing thing is the Majic
Ansible Roles:
1. Clone the git repository::
git clone http://code.majic.rs/majic-ansible-roles ~/majic-ansible-roles
2. Checkout the correct version of the roles::
cd ~/majic-ansible-roles/
git checkout -b 1.0.0 1.0.0
Preparing the basic site configuration
--------------------------------------
Phew... Now that was a bit tedious and boring... But at least you are now ready
to set-up your own site :)
First of all, let's set-up some basic directory structure and configuration:
1. Create Ansible configuration file.
:file:`~/mysite/ansible.cfg`::
[defaults]
roles_path=/home/ansible/majic-ansible-roles/roles:/home/ansible/mysite/roles
force_handlers = True
retry_files_save_path = /home/ansible/mysite/retry
inventory = /home/ansible/mysite/hosts
2. Create directory where retry files will be stored at (so they woudln't
pollute your home directory)::
mkdir ~/mysite/retry
3. Create the hosts file.
:file:`~/mysite/hosts`::
[preseed]
localhost ansible_connection=local
[communications]
comms.example.com
[web]
www.example.com
4. Create directory where playbooks files will be stored at (the top-level
ones)::
mkdir ~/mysite/playbooks/
5. Create directory where variables will be stored at::
mkdir ~/mysite/group_vars/
6. Before moving ahead, we should also create SSH private/public key pair that
will be used by Ansible for connecting to destination servers, as well as
for some roles::
ssh-keygen -f ~/.ssh/id_rsa -N ''
Preseed files
-------------
The ``preseed`` role is useful for generating Debian preseed files. Preseed
files can be used for automating the Debian installation process.
Preseed files are commonly created on the Ansible host, and then in some way
served to the servers using them during install.
So, let's set this up for start:
1. First of all, create the playbook for generating the preseed files locally.
:file:`~/mysite/playbooks/preseed.yml`::
---
- hosts: preseed
roles:
- preseed
2. And that is about it to be able to actually use this particular role! So
let's try running it::
workon mysite
ansible-playbook playbooks/preseed.yml
3. If all went well, you should have two files now:
* :file:`~/mysite/preseed_files/comms.example.com.cfg` and
* :file:`~/mysite/preseed_files/www.example.com.cfg`
4. You can have a look at them, but you might notice the settings in the file
might not be to your liking. In particular, it could be using wrong timezone,
defaulting to DHCP for network configuration etc. Let's concentrate on making
the network configuration changes - this is the main thing that will probably
differ in your environment. Create a new configuration file:
:file:`~/mysite/group_vars/preseed.yml`::
---
# Set your default (initial) root password.
preseed_root_password: changeit
# Use manual network configuration (no DHCP).
preseed_network_auto: no
# Set the gateway for all servers.
preseed_gateway: 10.32.64.1
# Set the netmask for all servers.
preseed_netmask: 255.255.255.0
# Set the DNS for all servers.
preseed_dns: 10.32.64.1
# Set the domain for all servers.
preseed_domain: example.com
# Set the server-specific options.
preseed_server_overrides:
comms.example.com:
hostname: comms
ip: 10.32.64.19
www.example.com:
hostname: www
ip: 10.32.64.20
5. Now re-run the preseed playbook::
ansible-playbook playbooks/preseed.yml
6. The preseed files should have been updated now, and you should have the new
customised configuration files in the ``preseed_files`` directory. You can
now use these to install the servers.
Installing the servers with preseed files
-----------------------------------------
You have your preseed files now, so you can go ahead and install the servers
``comms.example.com`` and ``www.example.com`` using them with network
install CD. Have a look at `Debian
<https://www.debian.org/releases/stable/amd64/apbs02.html.en>`_ instructions for
more details.
If you need to, you can easily serve the preseed files from the Ansible server
with Python's built-in HTTP server::
cd ~/mysite/preseed_files/
python -m SimpleHTTPServer 8000
Bootstrapping servers for Ansible set-up
----------------------------------------
In order to effectively use Ansible, a small initial bootstrap always has to be
done for managed servers. This mainly involves set-up of Ansible users on the
destination machine, and distributing the SSH public keys for authroisation.
When you use the preseed configuration files to deploy a server, you get the
benefit of having the authorized_keys set-up for the root operating system,
making it easier to bootstrap the machines subsequently via Ansible.
Let's bootstrap our two machines now:
1. For start, create a dedicated playbook for the bootstrap process.
:file:`~/mysite/playbooks/bootstrap.yml`::
---
- hosts: [communications, web]
remote_user: root
roles:
- bootstrap
2. The ``bootstrap`` role actually has only one parameter - for specifying the
SSH key to deploy to authorized_keys file for the Ansible user on managed
server. This defaults to content of local file ``~/.ssh/id_rsa.pub``, so no
need to make any changes so far.
3. SSH into both machines at least once from the Ansible server in order to
store the SSH fingerprints into known hosts file::
ssh root@comms.example.com date
ssh root@www.example.com date
4. Now, simply run the bootstrap role against the two servers::
ansible-playbook playbooks/bootstrap.yml
6. At this point you won't be able to ssh into the machines with root account
anymore. You would be able to ssh into the machine via public key using the
``ansible`` user. The ``ansible`` user will also be granted password-less
sudo privileges.
7. After this you can finally move on to configuring what you really want -
common configuration and services for your site.
Common server configuration
---------------------------
Each server needs to share some common configuration in order to be functioning
properly. This includes set-up of some shared accounts, perhaps some hardening
etc.
Let's take care of this common configuration right away:
1. Create playbook for the communications server:
:file:`~/mysite/playbooks/communications.yml`::
---
- hosts: communications
remote_user: ansible
sudo: yes
roles:
- common
2. Create playbook for the web server:
:file:`~/mysite/playbooks/web.yml`::
---
- hosts: web
remote_user: ansible
sudo: yes
roles:
- common
3. Create the global site playbook:
:file:`~/mysite/playbooks/site.yml`::
---
- include: preseed.yml
- include: communications.yml
- include: web.yml
4. Time to create configuration for the role. Since this role is supposed to
set-up a common base, we'll set-up the variables file that applies to all
roles:
:file:`~/mysite/group_vars/all.yml`::
---
os_users:
- name: admin
uid: 1000
additional_groups:
- sudo
authorized_keys:
- "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
password: "{{ 'admin' | password_hash('sha512') }}"
common_packages:
- emacs24-nox
5. That's all for configuration, time to apply the changes::
ansible-playbook playbooks/site.yml
6. After this you should be able to ssh using the user ``admin`` via public
key. The ``admin`` user's password has also been set to ``admin``, and the
user will be member of ``sudo`` group.
Introducing LDAP
----------------
Since some of the services actually depend on LDAP, we'll go ahead and set that
one up first. This includes both the LDAP *server* and *client* configuration.
1. Update the playbook for communications server to include the LDAP client and
server roles (``ldap_client`` and ``ldap_server``, respectively).
:file:`~/mysite/playbooks/communications.yml`::
---
- hosts: communications
remote_user: ansible
sudo: yes
roles:
- common
- ldap_client
- ldap_server
2. Update the playbook for web server to include the LDAP client role
(``ldap_client``). You never know when it might come in handy :)
:file:`~/mysite/playbooks/web.yml`::
---
- hosts: web
remote_user: ansible
sudo: yes
roles:
- common
- ldap_client
3. Time to configure the roles. For start, let us configure the LDAP server
role. Keep in mind that there is a lot of default variables set-up by the
role itself, making our config rather super-short.
:file:`~/mysite/group_vars/communications.yml`::
---
ldap_admin_password: admin
ldap_server_organization: "Example Inc."
4. Phew. That was... Well, actually, easy :) Technically, only the LDAP admin
password *must* be set, but it's nice to have better organisation specified
than the default one. Let's add the LDAP client configuration next. We will
start off with global LDAP client configuration. In case of LDAP client,
we've got to be a bit more explicit.
:file:`~/mysite/group_vars/all.yml`::
# Take note how we set the base DN. By default the ldap_server role
# (defined up there) will use server's domain to form the base for LDAP.
ldap_client_config:
- comment: Set the base DN
option: BASE
value: dc=example,dc=com
- comment: Set the default URI
option: URI
value: ldap://comms.example.com/
- comment: Set the LDAP TLS truststore
option: TLS_CACERT
value: /etc/ssl/certs/truststore.pem
- comment: Enforce TLS
option: TLS_REQCERT
value: demand
5. Ok, so this looks nice and dandy... But, let's have a bit better
configuration on the communications server itself. Namely, on that one we
should be able to connect to socket with LDAP clients instead over TCP port.
:file:`~/mysite/group_vars/communications.yml`::
ldap_client_config:
- comment: Set the base DN
option: BASE
value: dc=example,dc=com
- comment: Set the default URI
option: URI
value: ldapi:///
- comment: Set the default bind DN, useful for administration.
option: BINDDN
value: cn=admin,dc=example,dc=com
- comment: Set the LDAP TLS truststore
option: TLS_CACERT
value: /etc/ssl/certs/truststore.pem
- comment: Enforce TLS
option: TLS_REQCERT
value: demand
6. Ok, time to re-run the playbooks again... Wait a minute, something is missing
here... Oh, right, forgot to mention one thing - Majic Ansible Roles use TLS
throughout wherever possible. In other words, you *must* have TLS private
keys and certificates issued by some CA for all servers in order to be able
to use most of the roles (actually, you need them issued per *service*). This
includes ``ldap_server`` too. So, let's make a slight detour to create a CA
of our own, plus the necessary server certificate for the LDAP service...
1. Let's first install a couple of more tools on the Ansible server, since we
will be using ``certtool`` for our improvised CA needs::
apt-get install gnutls-bin
2. Create directory where the private keys and certificates will be stored
at::
mkdir ~/mysite/tls/
3. It is time to create a couple of templates for the ``certtool`` so it
would know what extensions and content to have in the certificates:
:file:`~/mysite/tls/ca.cfg`::
organization = "Example Inc."
country = "SE"
cn = "Example Inc. Test Site CA"
expiration_days = 1825
ca
cert_signing_key
crl_signing_key
:file:`~/mysite/tls/comms.example.com_ldap.cfg`::
organization = "Example Inc."
country = SE
cn = "Exampe Inc. LDAP Server"
expiration_days = 365
dns_name = "comms.example.com"
tls_www_server
signing_key
encryption_key
4. Almost there... Now let's generate the keys and certificates::
certtool --sec-param high --generate-privkey --outfile ~/mysite/tls/ca.key
certtool --template ~/mysite/tls/ca.cfg --generate-self-signed --load-privkey ~/mysite/tls/ca.key --outfile ~/mysite/tls/ca.pem
certtool --sec-param normal --generate-privkey --outfile ~/mysite/tls/comms.example.com_ldap.key
certtool --generate-certificate --load-ca-privkey ~/mysite/tls/ca.key --load-ca-certificate ~/mysite/tls/ca.pem --template ~/mysite/tls/comms.example.com_ldap.cfg --load-privkey ~/mysite/tls/comms.example.com_ldap.key --outfile ~/mysite/tls/comms.example.com_ldap.pem
5. And just one more small tweak - we need to provide a truststore PEM file
containing all CA certificates in the chain. In this particular case we
have a super-simple hierarchy (root CA is also issuing the end entity
certificates), so simply make a copy of the ``ca.pem``. The
``truststore.pem`` file is picked-up automatically by many other roles::
cp ~/mysite/tls/ca.pem ~/mysite/tls/truststore.pem
7. With private keys and certificates in place, we are almost ready to re-run
the playbooks! Now, just a *small* tweak to the general configuration, and
all should be fine.
:file:`~/mysite/group_vars/all.yml`::
tls_private_key_dir: "~/mysite/tls/"
tls_certificate_dir: "~/mysite/tls/"
ca_certificates:
- "~/mysite/tls/truststore.pem"
8. And now as finishing touch, simply run the playbooks again::
ansible-playbook playbooks/site.yml
Adding mail server
------------------
The next thing in line is to implement the mail server capability. *Majic
Ansible Roles* come with two distinct mail server-related roles. One for
setting-up a mail server host (with authenticated IMAP, SMTP etc), and one for
setting-up a mail forwarder (for having the rest of your servers relay through
the mail server host).
The mail server role looks-up available mail domains, users, and aliases in the
LDAP directory. This has already been set-up on the server
``comms.example.com``, but some modifications will be necessary to
configuration.
1. Update the playbook for communications server to include the mail server
role.
:file:`~/mysite/playbooks/communications.yml`::
---
- hosts: communications
remote_user: ansible
sudo: yes
roles:
- common
- ldap_client
- ldap_server
- mail_server
2. Let's configure the role next.
:file:`~/mysite/group_vars/communications.yml`::
# Set the LDAP URL to connect through. Keep in mind TLS is required.
mail_ldap_url: ldap://comms.example.com/
# Here we need to point to the base DN of LDAP server. A bunch of entries
# will need to exist under it for service to function correctly, though.
mail_ldap_base_dn: dc=example,dc=com
# Separate LDAP entries are used for Postfix/Dovecot
# authentication. Therefore we have two passwords here.
mail_ldap_postfix_password: postfix
mail_ldap_dovecot_password: dovecot
# Setting uid/gid is optional, but you might have a policy on how to
# assign UIDs and GIDs, so it is convenient to be able to change this.
mail_user_uid: 5000
mail_user_gid: 5000
3. There are two distinct mail services that need to access the LDAP directory -
*Postfix* (serving as an SMTP server), and *Dovecot* (serving as an IMAP
server). These two need their own dedicated LDAP entries on the LDAP server in
order to log-in. Luckily, it is easy to create such entries through the options
provided by the LDAP server role. In addition to this, the Postfix and Dovecot
services will check if users are members of ``mail`` group in LDAP directory
before accepting them as valid mail users. Once again, the LDAP server role
comes with a simple option for creating groups.
:file:`~/mysite/group_vars/communications.yml`::
# Don't forget, the passwords here must match with passwords specified
# under for mail_ldap_postfix_password/mail_ldap_dovecot_password.
ldap_server_consumers:
- name: postfix
password: postfix
- name: dovecot
password: dovecot
ldap_server_groups:
- name: mail
4. Ok, so now our SMTP and IMAP service can log-in into the LDAP server to
look-up the mail server information. We have also defined the mail group for
limitting which users get mail service. However, we don't have any
user/domain information yet. So let's change that, using the ``ldap_entries``
option from LDAP server role.
.. warning::
Long-term, you probably want to manage these entries manually or through
other means than the ``ldap_entries`` option. The reason for this is
because this type of data in LDAP directory can be considered more of an
operational/application data than configuration data that frequently
changes (especially the user passwords/info. Keep in mind that you shold
also be backing-up your LDAP directory on regular basis ;)
:file:`~/mysite/group_vars/communications.yml`::
ldap_entries:
# Create first a couple of user entries. Don't forget to set the
# "mail" attribute for them.
- dn: uid=johndoe,ou=people,dc=example,dc=com
objectClass:
- inetOrgPerson
uid: johndoe
cn: John Doe
sn: Doe
userPassword: johndoe
mail: john.doe@example.com
- dn: uid=janedoe,ou=people,dc=example,dc=com
objectClass:
- inetOrgPerson
uid: janedoe
cn: Jane Doe
sn: Doe
userPassword: janedoe
mail: jane.doe@example.com
# Now, let's add the two users to the mail group. Observe that we use
# the "state: append" option. This is a bit of a cheat since the
# ldap_entries option passes the provided entries directly to the
# ldap_entry module. "state: append" will make sure we don't overwrite
# the group, and instead add the attributes to it (in this case we add
# the two users).
- dn: cn=mail,ou=groups,dc=example,dc=com
uniqueMember:
- uid=johndoe,ou=people,dc=example,dc=com
- uid=janedoe,ou=people,dc=example,dc=com
state: append
# Let's register our domain in LDAP directory.
- dn: dc=example.com,ou=domains,ou=mail,ou=services,dc=example,dc=com
objectClass: dNSDomain
dc: "example.com"
# Finally, for the lolz, let's also add the standard postmaster alias
# for our domain.
- dn: cn=postmaster@example.com,ou=aliases,ou=mail,ou=services,dc=example,dc=com
objectClass: nisMailAlias
cn: postmaster@example.com
rfc822MailMember: john.doe@example.com
5. Once again, before we apply the configuration, we must make sure the
necessary TLS private keys and certificates are available. In this particular
case, we need to set-up separate key/certificate pair for both the SMTP and
IMAP service:
1. Create new templates for ``certtool``:
:file:`~/mysite/tls/comms.example.com_smtp.cfg`::
organization = "Example Inc."
country = SE
cn = "Exampe Inc. SMTP Server"
expiration_days = 365
dns_name = "comms.example.com"
tls_www_server
signing_key
encryption_key
:file:`~/mysite/tls/comms.example.com_imap.cfg`::
organization = "Example Inc."
country = SE
cn = "Exampe Inc. IMAP Server"
expiration_days = 365
dns_name = "comms.example.com"
tls_www_server
signing_key
encryption_key
2. Create the keys and certificates for SMATP/IMAP services based on the templates::
certtool --sec-param normal --generate-privkey --outfile ~/mysite/tls/comms.example.com_smtp.key
certtool --generate-certificate --load-ca-privkey ~/mysite/tls/ca.key --load-ca-certificate ~/mysite/tls/ca.pem --template ~/mysite/tls/comms.example.com_smtp.cfg --load-privkey ~/mysite/tls/comms.example.com_smtp.key --outfile ~/mysite/tls/comms.example.com_smtp.pem
certtool --sec-param normal --generate-privkey --outfile ~/mysite/tls/comms.example.com_imap.key
certtool --generate-certificate --load-ca-privkey ~/mysite/tls/ca.key --load-ca-certificate ~/mysite/tls/ca.pem --template ~/mysite/tls/comms.example.com_imap.cfg --load-privkey ~/mysite/tls/comms.example.com_imap.key --outfile ~/mysite/tls/comms.example.com_imap.pem
6. Configuration and TLS keys have ben set-up, so it is time to apply the changes::
ansible-playbook playbooks/site.yml
7. If no errors have been reported, at this point you should have two mail
accounts - ``john.doe@example.com``, with password ``johndoe``, and
``jane.doe@example.com``, with password ``janedoe``. In this particular set-up,
the mail addresses are used as usernames. If you want to test it out, simply
install ``swaks`` on yout ansible machine, and run something along the lines of::
swaks --to john.doe@example.com --server comms.example.com
swaks --to jane.doe@example.com --server comms.example.com
Of course, free feel to test out the mail server using mail client of your
choice.
Setting-up mail relaying from web server
------------------------------------------
With the mail server set-up, the next thing to do would be to set-up the SMTP
server on web server to relay mails via the communications server. This way we
can make sure that mail that gets sent via local SMTP to external addresses on
the web server goes through anti-virus scans and such.
1. Update the web server list of roles to include the mail forwarder role.
:file:`~/mysite/playbooks/web.yml`::
---
- hosts: web
remote_user: ansible
sudo: yes
roles:
- common
- mail_forwarder
2. The next thing is to set-up the configuration for the new role. Web server
configuration has not been touched before, so this will be a new
configuration file.
:file:`~/mysite/group_vars/web.yml`::
---
# First, let's make sure any mails directed to localhost root account get
# forwarded to one of our mail users as well.
local_mail_aliases:
root: root john.doe@example.com
# Now signal the local SMTP to relay any non-local mails via our
# communications server. Don't forget to specify your own IP address
# here. Without this option, the SMTP would send out the mails directly.
smtp_relay_host: comms.example.com
3. Although we have told our web server to use the communications server as
relay for non-local mail, the communications server is not aware of
this. This would result in the communications server refusing all relay
attempts (if not, it would be an open relay, which is bad).
So, let's fix this a bit - we have a configuration option for the mail server
for exactly this purpose.
:file:`~/mysite/group_vars/communications.yml`::
# We want to allow relaying of mails from our web server here. Beware the
# IP spoofing, though! Don't forget to change the bellow IP for your
# server ;)
smtp_allow_relay_from:
- 10.32.64.20
4. Let's apply the changes::
ansible-playbook playbooks/site.yml
5. After this you may want to test out sending mail via web server's local SMTP
to the root user (to see if the aliasing works), and to some external mail
address - just run something along the lines of::
swaks --to root@localhost --server localhost
swaks --to YOUR_MAIL --server localhost
If all went well, you should be able to see a new mail in John Doe's mailbox,
as well as your own mailbox.
Adding XMPP server
------------------
Now that the users can communicate via mail server, we might as well add support
for some instant messaging. For this purpose, we will use the ``xmpp_server``
role.
1. Update the playbook for communications server to include the XMPP server
role.
:file:`~/mysite/playbooks/communications.yml`::
---
- hosts: communications
remote_user: ansible
sudo: yes
roles:
- common
- ldap_client
- ldap_server
- mail_server
- xmpp_server
2. Configure the role.
:file:`~/mysite/group_vars/communications.yml`::
# Set one of the users to also be an XMPP administrator.
xmpp_administrators:
- john.doe@example.com
# Unfortunately, XMPP can't look-up domains via LDAP, so we need to be
# explicit here.
xmpp_domains:
- example.com
# Simply point the XMPP server to base DN of LDAP server, and let it use
# specific directory structure it expects.
xmpp_ldap_base_dn: dc=example,dc=com
# Password for logging-in into the LDAP directory.
xmpp_ldap_password: prosody
# Where the LDAP server is located at. Full-blown LDAP URIs are _not_
# supported!
xmpp_ldap_server: comms.example.com
3. Now, like in case of the mail server role, we need to set-up authentication
for the XMPP service. In this particular case a single consumer is present -
Prosody itself. We should also create the group for granting the users right
to use the service.
:file:`~/mysite/group_vars/communications.yml`::
# Just make sure the new entry is added for the prosody user - you can
# leave the postfix/dovecot intact in your file if you use different
# passwords. Keep in mind password for prosody user must match with
# password specified under xmpp_ldap_password.
ldap_server_consumers:
- name: postfix
password: postfix
- name: dovecot
password: dovecot
- name: prosody
password: prosody
# And simply append a new group here...
ldap_server_groups:
- name: mail
- name: xmpp
4. Ok, configuration of the role is almost complete. You may have noticed that
we still haven't added any users to the new LDAP group called "xmpp". So let
us correct this in similar way as we did for the mail server. Since we have
the user entries already, no need to recreate them here. We will just update
the group membership instead.
.. warning::
Same warning applies here as for mail server role for managing the
user/group entries! Scroll up and re-read it if you missed it!
:file:`~/mysite/group_vars/communications.yml`::
# Don't replace the entire ldap_entries, just append the new group
# modification.
ldap_entries:
# Add the two users to the xmpp group. Observe that we use
# the "state: append" option. This is a bit of a cheat since the
# ldap_entries option passes the provided entries directly to the
# ldap_entry module. "state: append" will make sure we don't overwrite
# the group, and instead add the attributes to it (in this case we add
# the two users).
- dn: cn=xmpp,ou=groups,dc=example,dc=com
uniqueMember:
- uid=johndoe,ou=people,dc=example,dc=com
- uid=janedoe,ou=people,dc=example,dc=com
state: append
5. Do you know what it is time to do now? Yes! Create some more TLS private keys
and certificates, this time for our XMPP server ;)
1. Create new template for ``certtool``:
:file:`~/mysite/tls/comms.example.com_xmpp.cfg`::
organization = "Example Inc."
country = SE
cn = "Exampe Inc. XMPP Server"
expiration_days = 365
dns_name = "comms.example.com"
tls_www_server
signing_key
encryption_key
2. Create the keys and certificates for XMPP service based on the template::
certtool --sec-param normal --generate-privkey --outfile ~/mysite/tls/comms.example.com_xmpp.key
certtool --generate-certificate --load-ca-privkey ~/mysite/tls/ca.key --load-ca-certificate ~/mysite/tls/ca.pem --template ~/mysite/tls/comms.example.com_xmpp.cfg --load-privkey ~/mysite/tls/comms.example.com_xmpp.key --outfile ~/mysite/tls/comms.example.com_xmpp.pem
6. Apply the changes::
ansible-playbook playbooks/site.yml
7. If no errors have been reported, at this point you should have two users
capable of using the XMPP service - one with username
``john.doe@example.com`` and one with username ``jane.doe@example.com``. Same
passwords are used as for when you were creating the two users for mail
server. For testing you can turn to your favourite XMPP client (I don't know
of any CLI-based tools to test the XMPP server functionality, unfortunately).
Taking a step back - preparing for web server
---------------------------------------------
Up until now the usage instructions have touched almost exclisively on the
communications server. That is, we haven't done anything beyond the basic set-up
of the web server.
Let us first define what we want to deploy on the web server. Since the goal is
to demonstrate the full spectrum of *Majic Ansible Roles*, we will stick to the
so far unused roles for this purpose. So, here is the plan:
1. First off, we will set-up the web server. This will be necessary no matter
what web application we decide to deploy later on.
2. Next, we will set-up a database server. Why? Well, most web applications
need to use some sort of database to store all the data, so we might as well
try to take that one out of the way.
3. With this basic deployment for a web server in place, we can move on to
setting-up a couple of web applications. For the purpose of the usage
instructions, we will deploy the following two:
1. `The Bug Genie <https://thebuggenie.org/>`_ - an issue tracker. To keep
things simple, we will not integrate it with our LDAP server (although
this is supported and possible). Being written in PHP, this will
demonstrate the role for PHP web application deployment.
2. `Django Wiki <https://github.com/django-wiki/django-wiki>`_ - a wiki
application written in Django. This will serve as a demo of how the WSGI
role works.
It should be noted that the web application deployment roles are a bit more
complex - namely they are not meant to be used directly, but instead as a
dependency for a custom role. They do come with decent amount of batteries
included, and also play nice with the web server role, though.
With all the above noted, let us finally move on to the next step.
Setting-up the web server
-------------------------
Finally we are moving on to the web server deployment, and we shell start
with... Well, erm, web server deployment! To be more precise, we will set-up
Nginx on the server.
1. Update the playbook for web server to include the web server role.
:file:`~/mysite/playbooks/web.yml`::
---
- hosts: web
remote_user: ansible
sudo: yes
roles:
- common
- ldap_client
- mail_forwarder
- web_server
2. You know the drill, role configuration comes up next. Actually... The web
server role parameters are all optional, and they default to some ok-ish
values. But let us spicen up things a bit nevertheless.
:file:`~/mysite/group_vars/web.yml`::
web_default_title: "Welcome to default page!"
web_default_message: "Nothing to see here, move along..."
3. The only thing left now is to create the TLS private key/certificate pair
that should be used for default virtual host.
1. Create new template for ``certtool``:
:file:`~/mysite/tls/www.example.com_https.cfg`::
organization = "Example Inc."
country = SE
cn = "Exampe Inc. Web Server"
expiration_days = 365
dns_name = "www.example.com"
tls_www_server
signing_key
encryption_key
2. Create the keys and certificates for default web server virtual host based
on the template::
certtool --sec-param normal --generate-privkey --outfile ~/mysite/tls/www.example.com_https.key
certtool --generate-certificate --load-ca-privkey ~/mysite/tls/ca.key --load-ca-certificate ~/mysite/tls/ca.pem --template ~/mysite/tls/www.example.com_https.cfg --load-privkey ~/mysite/tls/www.example.com_https.key --outfile ~/mysite/tls/www.example.com_https.pem
4. Apply the changes::
ansible-playbook playbooks/site.yml
5. If no errors have been reported, at this point you should have a default web
page available and visible at https://www.example.com/. Feel free to try it
out with some browser. Keep in mind you will get a warning about the
untrusted certificate!
Adding the database server
--------------------------
Since both of the web applications we want to deploy need a database, we will
proceed to set-up the database server role on the web server itself. *Majic
Ansible Roles* in particular comes with a role that will deploy MariaDB database
server.
1. Update the playbook for web server to include the database server role.
:file:`~/mysite/playbooks/web.yml`::
---
- hosts: web
remote_user: ansible
sudo: yes
roles:
- common
- ldap_client
- mail_forwarder
- web_server
- database_server
2. Now let's configure the role. This is rather simplistic, since we only need
to set the database server root (admin) password.
:file:`~/mysite/group_vars/web.yml`::
db_root_password: root
3. No TLS support has been implemented for this role (yet), so simply apply the
changes::
ansible-playbook playbooks/site.yml
4. If no errors have been reported, you should have a database server up and
running on the web server. You should be able to log-in using password
``root`` via command::
mysql -uroot -p
Of course, no database has been created for either of the web applications,
but we will get to that one later (there is a dedicated ``database`` role
which can be combined with web app roles for this purpose).
Deploying a PHP web application (The Bug Genie)
-----------------------------------------------
We have some basic infrastructure up and running now on our web server, so we
shall move on to setting-up a PHP web application on it. As mentioned before, we
will take The Bug Genie as an example.
For this we will create a local role in our site to take care of it. This role
will in turn utilise two roles coming from *Majic Ansible Roles* that will make
our life (a little) easier.
To make the example a bit simpler, no parameters will be introducd to this role
(not even the password for database etc).
Here is also a couple of useful pointers regarding the ``php_website`` role
we'll be using for the PHP part:
* The role is designed to execute every application via dedicated user and
group. The user/group name is automatically derived from the FQDN of website,
for example ``web-tbg_example_com``.
* PHP applications are executed via FastCGI, using the ``php5-fpm`` package.
* Static content (non-PHP) is served directly by *Nginx*.
* For administrative purposes you can use a separate user that you have created
before (for example via the ``common`` role). This user will get added to
application's group.
* Each web application gets distinct sub-directory under ``/var/www``, named
after the FQDN. All sub-directories created under there are created with
``2750`` permissions, with ownership set to admin user, and group set to the
application's group. In other words, all directories will have ``SGID`` bit
set-up, allowing you to create files/directories that will have their group
automatically set to the group of the parent directory.
* Files are served (both by *Nginx* and *php5-fpm*) from sub-directory called
``htdocs`` (located in website directory). For example
``/var/www/tbg.example.com/htdocs/``. Normally, this can be a symlink to some
other sub-directory within the website directory (useful for having multiple
versions for easier downgrades etc).
* Combination of admin user membership in application group, ``SGID``
permission, and the way ownership of sub-directories is set-up usually means
that the administrator will be capable of managing application files, and
application can be granted write permissions to a *minimum* of necessary
files.
.. warning::
Just keep in mind that some file-management commands, like ``mv``, do *not*
respect the ``SGID`` bit. In fact, I would recommend using ``cp`` when you
deploy new files to the directory instead (don't simply move them from your
home).
1. Start-off with creating the necessary directories for the new role::
mkdir -p ~/mysite/roles/tbg/{tasks,meta,files}/
2. Let's set-up role dependencies, reusing some common roles to make our life
easier.
:file:`~/mysite/roles/tbg/meta/main.yml`::
---
dependencies:
# Ok, so this role helps us set-up Nginx virtual host for serving our
# app.
- role: php_website
# We shall let our admin account be able to read/write files
# belonging to the application. This allows us to use regular user
# (admin in this case) without sudo.
admin: admin
# This will set-up a new virtual host for our app.
fqdn: tbg.example.com
# Some additional packages are required in order to deploy and use TBG.
packages:
- php5-gd
- php5-curl
- git
- php5-mysql
- expect
# Set-up URL rewriting. This is based on public/.htaccess file from
# TBG.
php_rewrite_urls:
- ^(.*)$ /index.php?url=$1
# We don't necessarily need this, but in case you have a policy on
# uid/gid usage, this is useful. Take note that below value is used
# for both the dedicated uid and gid for application user.
uid: 2000
# And this role sets up a new dedicated database for our web
# application.
- role: database
# This is both the database name, _and_ name of the database user
# that will be granted full privileges on the database.
db_name: tbg
# This will be the password of our user 'tbg' to access the
# database. Take note the user can only login from localhost.
db_password: tbg
3. Now for my favourite part again - creating private keys certificates! Why?
Because the ``php_website`` role requires a private key/certificate pair to
be deployed. So... Moving on:
1. Create new template for ``certtool``:
:file:`~/mysite/tls/tbg.example.com_https.cfg`::
organization = "Example Inc."
country = SE
cn = "Exampe Inc. Issue Tracker"
expiration_days = 365
dns_name = "tbg.example.com"
tls_www_server
signing_key
encryption_key
2. Create the keys and certificates for the application::
certtool --sec-param normal --generate-privkey --outfile ~/mysite/tls/tbg.example.com_https.key
certtool --generate-certificate --load-ca-privkey ~/mysite/tls/ca.key --load-ca-certificate ~/mysite/tls/ca.pem --template ~/mysite/tls/tbg.example.com_https.cfg --load-privkey ~/mysite/tls/tbg.example.com_https.key --outfile ~/mysite/tls/tbg.example.com_https.pem
4. Time to get our hands a bit more dirty... Up until now we didn't have to write
custom tasks, but at this point we need to.
:file:`~/mysite/roles/tbg/tasks/main.yml`::
---
- name: Define TBG version
set_fact: tbg_version=4.1.0
- name: Download the TBG archive
get_url: url=https://github.com/thebuggenie/thebuggenie/archive/v{{ tbg_version }}.tar.gz
dest="/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}.tar.gz"
sha256sum=0fd0a680ba281adc97d5d2c720e63b995225c99716a36eca6a198b8a5ebf8057
become: yes
become_user: admin
- name: Download Composer
get_url: url=https://getcomposer.org/download/1.0.0-alpha10/composer.phar
dest="/usr/local/bin/composer"
sha256sum=9f2c7d0364bc743bcde9cfe1fe84749e5ac38c46d47cf42966ce499135fd4628
owner=root group=root mode=755
- name: Unpack TBG
unarchive: src="/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}.tar.gz"
dest="/var/www/tbg.example.com/" copy=no
creates="/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}"
become: yes
become_user: admin
- name: Create TBG cache directory
file: path="/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}/cache" state=directory mode=2770
become: yes
become_user: admin
- name: Set-up writeable directories for TBG install
file: path="{{ item }}" mode=g+w
with_items:
- /var/www/tbg.example.com/thebuggenie-{{ tbg_version }}/
- /var/www/tbg.example.com/thebuggenie-{{ tbg_version }}/public/
- /var/www/tbg.example.com/thebuggenie-{{ tbg_version }}/core/config/
- name: Create symbolic link to TBG application
file: src="/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}/public"
path="/var/www/tbg.example.com/htdocs"
state=link
owner="admin" group="web-tbg_example_com" mode=2750
become: yes
become_user: admin
- name: Install TBG dependencies
composer: command=install working_dir="/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}"
become: yes
become_user: admin
- name: Deploy database configuration file for TBG
copy: src="b2db.yml" dest="/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}/core/config/b2db.yml"
mode=640 owner=admin group=web-tbg_example_com
- name: Deploy expect script for installing TBG
copy: src="tbg_expect_install" dest="/var/www/tbg.example.com/tbg_expect_install" mode=750
become: yes
become_user: admin
- name: Run TBG installer via expect script
command: /var/www/tbg.example.com/tbg_expect_install
chdir=/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}
creates=/var/www/tbg.example.com/thebuggenie-{{ tbg_version }}/installed
become: yes
become_user: admin
5. Set-up the files that are deployed via task above.
:file:`~/mysite/roles/tbg/files/b2db.yml`::
b2db:
username: "tbg"
password: "tbg"
dsn: "mysql:host=localhost;dbname=tbg"
tableprefix: ''
cacheclass: '\thebuggenie\core\framework\Cache'
:file:`~/mysite/roles/tbg/files/tbg_expect_install`::
#!/usr/bin/expect
spawn ./tbg_cli install --accept_license=yes --url_subdir=/ --use_existing_db_info=yes --enable_all_modules=yes --setup_htaccess=yes
expect "Press ENTER to continue with the installation: "
send "\r"
expect "Press ENTER to continue: "
send "\r"
interact
6. And... Let's add the new role to our web server.
:file:`~/mysite/playbooks/web.yml`::
---
- hosts: web
remote_user: ansible
sudo: yes
roles:
- common
- ldap_client
- mail_forwarder
- web_server
- database_server
- tbg
7. Apply the changes::
ansible-playbook playbooks/site.yml
8. At this point TBG has been installed, and you should be able to open the URL
https://tbg.example.com/ (or http://tbg.example.com/) and log-in into
*The Bug Genie* with username ``administrator`` and password ``admin``.
Deploying a WSGI application (Django Wiki)
------------------------------------------
Next thing up will be to deploy a WSGI Python application - our wiki website.
Similar to the PHP application deployment, we will use a couple of roles to make
it easier to deploy it in a standardised manner, and we will not have any kind
of parameters for configuring the application role.
Most of the notes on how the application is deployed in case of ``php_website``
role also stand for the ``wsgi_website`` role, but we will reitarte and clarify
them a bit just to be on the safe side:
* The role is designed to execute every application via dedicated user and
group. The user/group name is automatically derived from the FQDN of website,
for example ``web-wiki_example_com``.
* WSGI applications are executed via *Gunicorn*. The WSGI server listens on a
Unix socket, making the socket accessible by *Nginx*.
* Static content is served directly by *Nginx*.
* For administrative purposes you can use a separate user that you have created
before (for example via the ``common`` role). This user will get added to
application's group. The administrator will also be able to switch to website
virtual environment using the ``workon`` command from ``virtualenv-wrapper``
package.
* Each web application gets distinct sub-directory under ``/var/www``, named
after the FQDN. All sub-directories created under there are created with
``2750`` permissions, with ownership set to admin user, and group set to the
application's group. In other words, all directories will have ``SGID`` bit
set-up, allowing you to create files/directories that will have their group
automatically set to the group of the parent directory.
* Each WSGI website gets a dedicated virtual environment, stored in the
sub-directory ``virtualenv`` of the website directory, for example
``/var/www/wiki.example.com/virtualenv``.
* Static files are served from sub-directory ``htdocs`` in the website
directory, for example ``/var/www/wiki.example.com/htdocs/``.
* The base directory where your website/application code should be at is
expected to be in sub-directory ``code`` in the website directory, for example
``/var/www/wiki.example.com/code/``.
* Combination of admin user membership in application group, ``SGID``
permission, and the way ownership of sub-directories is set-up usually means
that the administrator will be capable of managing application files, and
application can be granted write permissions to a *minimum* of necessary
files.
.. warning::
Just keep in mind that some file-management commands, like ``mv``, do *not*
respect the ``SGID`` bit. In fact, I would recommend using ``cp`` when you
deploy new files to the directory instead (don't simply move them from your
home).
1. Set-up the necessary directories first::
mkdir -p ~/mysite/roles/wiki/{tasks,meta,files}/
2. Set-up some role dependencies, reusing the common role infrastructure.
:file:`~/mysite/roles/wiki/meta/main.yml`::
---
dependencies:
- role: wsgi_website
admin: admin
fqdn: wiki.example.com
# Most of these packages are needed for building Python packages.
packages:
- build-essential
- python-dev
- libjpeg-dev
- libzip-dev
- libtiff-dev
- libfreetype6-dev
- liblcms2-dev
- libwebp-dev
- libopenjpeg-dev
- libmariadb-client-lgpl-dev
- libmariadb-client-lgpl-dev-compat
static_locations:
- /static/
uid: 2001
virtualenv_packages:
- pillow
- wiki
- MySQL-python
wsgi_application: wiki_example_com.wsgi:application
- role: database
db_name: wiki
db_password: wiki
3. Let's create a dedicated private key/certificate pair for the wiki website:
1. Create new template for ``certtool``:
:file:`~/mysite/tls/wiki.example.com_https.cfg`::
organization = "Example Inc."
country = SE
cn = "Exampe Inc. Wiki"
expiration_days = 365
dns_name = "wiki.example.com"
tls_www_server
signing_key
encryption_key
2. Create the keys and certificates for the application::
certtool --sec-param normal --generate-privkey --outfile ~/mysite/tls/wiki.example.com_https.key
certtool --generate-certificate --load-ca-privkey ~/mysite/tls/ca.key --load-ca-certificate ~/mysite/tls/ca.pem --template ~/mysite/tls/wiki.example.com_https.cfg --load-privkey ~/mysite/tls/wiki.example.com_https.key --outfile ~/mysite/tls/wiki.example.com_https.pem
4. At this point we have exhausted what we can do with the built-in roles. Time
to add some custom tasks.
:file:`~/mysite/roles/wiki/tasks/main.yml`::
---
- name: Set-up symbolic link for mysql_config for building MySQL-python
file: src="/usr/bin/mariadb_config" dest="/usr/bin/mysql_config"
state="link"
- name: Create Django project directory
file: dest="/var/www/wiki.example.com/code" state=directory
owner=admin group=web-wiki_example_com
mode=2750
- name: Start Django project for the Wiki website
command: /var/www/wiki.example.com/virtualenv/bin/exec django-admin.py startproject wiki_example_com /var/www/wiki.example.com/code
chdir=/var/www/wiki.example.com
creates=/var/www/wiki.example.com/code/wiki_example_com
become: yes
become_user: admin
- name: Deploy settings for wiki website
copy: src="{{ item }}" dest="/var/www/wiki.example.com/code/wiki_example_com/{{ item }}"
mode=640 owner=admin group=web-wiki_example_com
with_items:
- settings.py
- urls.py
notify:
- Restart website wiki.example.com
- name: Deploy project database and deploy static files
django_manage: command="{{ item }}"
app_path="/var/www/wiki.example.com/code/"
virtualenv="/var/www/wiki.example.com/virtualenv/"
become: yes
become_user: admin
with_items:
- syncdb
- migrate
- collectstatic
- name: Deploy the superadmin creation script
copy: src="create_superadmin.py" dest="/var/www/wiki.example.com/code/create_superadmin.py"
owner=admin group=web-wiki_example_com mode=750
- name: Create initial superuser
command: /var/www/wiki.example.com/virtualenv/bin/exec ./create_superadmin.py
chdir=/var/www/wiki.example.com/code/
become: yes
become_user: admin
register: wiki_superuser
changed_when: wiki_superuser.stdout == "Created superuser."
5. There is a couple of files that we are deploying through the above
tasks. Let's create them as well.
:file:`~/mysite/roles/wiki/files/settings.py`::
"""
Django settings for wiki_example_com project.
For more information on this file, see
https://docs.djangoproject.com/en/1.6/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.6/ref/settings/
"""
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'l^q+t$7h$ebls)v34+w9m9v4$n+^(9guxqntu&#cc4m&lfd-6_'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
TEMPLATE_DEBUG = False
ALLOWED_HOSTS = ["wiki.example.com", "localhost"]
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
'django.contrib.humanize',
'django_nyt',
'mptt',
'sekizai',
'sorl.thumbnail',
'wiki',
'wiki.plugins.attachments',
'wiki.plugins.notifications',
'wiki.plugins.images',
'wiki.plugins.macros',
'south',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
ROOT_URLCONF = 'wiki_example_com.urls'
WSGI_APPLICATION = 'wiki_example_com.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.6/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'wiki',
'USER': 'wiki',
'PASSWORD': 'wiki',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.6/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Europe/Stockholm'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.6/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = '/var/www/wiki.example.com/htdocs/static'
from django.conf import settings
TEMPLATE_CONTEXT_PROCESSORS = settings.TEMPLATE_CONTEXT_PROCESSORS + (
"django.core.context_processors.debug",
"django.core.context_processors.request",
"sekizai.context_processors.sekizai",
)
SITE_ID=1
:file:`~/mysite/roles/wiki/files/urls.py`::
from django.conf.urls import patterns, include, url
from wiki.urls import get_pattern as get_wiki_pattern
from django_nyt.urls import get_pattern as get_nyt_pattern
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'wiki_example_com.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
)
urlpatterns += patterns('',
(r'^notifications/', get_nyt_pattern()),
(r'', get_wiki_pattern())
)
:file:`~/mysite/roles/wiki/files/create_superadmin.py`::
#!/usr/bin/env python
import os
os.environ['DJANGO_SETTINGS_MODULE']='wiki_example_com.settings'
from django.conf import settings
from django.contrib.auth.models import User
User.objects.all()
if len(User.objects.filter(username="admin")) == 0:
User.objects.create_superuser('admin', 'john.doe@example.com', 'admin')
print("Created superuser.")
6. Time to add the new role to our web server.
:file:`~/mysite/playbooks/web.yml`::
---
- hosts: web
remote_user: ansible
sudo: yes
roles:
- common
- ldap_client
- mail_forwarder
- web_server
- database_server
- tbg
- wiki
7. Apply the changes::
ansible-playbook playbooks/site.yml
8. At this point Django Wiki has been installed, and you should be able to open
the URL https://wiki.example.com/ (or http://wiki.example.com/) and log-in
into *Django Wiki* with username ``admin`` and password ``admin``.
|