Browse Source

Greenplum provisioning Ansible role

master
Maxim Likhachev 3 years ago
commit
6af6404c63
  1. 8
      .ansible-lint
  2. 33
      Makefile
  3. 93
      README.md
  4. 27
      add-users.yml
  5. 26
      ansible.cfg
  6. 1
      files/pkg/postgis-2.5.4+pivotal.2.build.3-gp6-rhel7-x86_64.gppkg
  7. 2
      files/rpm/greenplum-db-6.7.0-rhel7-x86_64.rpm
  8. 89
      inventory/sample/files/ssh/gpadmin
  9. 25
      inventory/sample/files/ssh/gpadmin.pub
  10. 89
      inventory/sample/files/ssh/provision
  11. 25
      inventory/sample/files/ssh/provision.pub
  12. 68
      inventory/sample/group_vars/all/all.yml
  13. 10
      inventory/sample/hosts.ini
  14. 8
      roles/common/defaults/main.yml
  15. 12
      roles/common/handlers/main.yml
  16. 11
      roles/common/tasks/dependencies.yml
  17. 65
      roles/common/tasks/disks.yml
  18. 9
      roles/common/tasks/firewall.yml
  19. 24
      roles/common/tasks/kernel.yml
  20. 25
      roles/common/tasks/limits.yml
  21. 15
      roles/common/tasks/main.yml
  22. 55
      roles/common/tasks/ssh.yml
  23. 143
      roles/common/tasks/sysctl.yml
  24. 6
      roles/common/tasks/timezone.yml
  25. 25
      roles/common/tasks/users.yml
  26. 16
      roles/greenplum-master/defaults/main.yml
  27. 39
      roles/greenplum-master/handlers/main.yml
  28. 93
      roles/greenplum-master/tasks/extensions.yml
  29. 106
      roles/greenplum-master/tasks/init.yml
  30. 46
      roles/greenplum-master/tasks/main.yml
  31. 29
      roles/greenplum-master/tasks/roles.yml
  32. 71
      roles/greenplum-master/templates/gpinitsystem_config.j2
  33. 29
      roles/greenplum-master/templates/greenplum.service.j2
  34. 3
      roles/greenplum-master/templates/hostfile_gpinitsystem.j2
  35. 4
      roles/greenplum-segment/defaults/main.yml
  36. 14
      roles/greenplum-segment/tasks/main.yml
  37. 15
      roles/greenplum/defaults/main.yml
  38. 111
      roles/greenplum/tasks/extensions-contrib.yml
  39. 67
      roles/greenplum/tasks/main.yml
  40. 8
      roles/ntpd/defaults/main.yml
  41. 16
      roles/ntpd/handlers/main.yml
  42. 17
      roles/ntpd/tasks/main.yml
  43. 60
      roles/ntpd/templates/ntp.conf.j2
  44. 19
      roles/prometheus-exporter/defaults/main.yml
  45. 16
      roles/prometheus-exporter/handlers/main.yml
  46. 27
      roles/prometheus-exporter/tasks/main.yml
  47. 27
      roles/prometheus-exporter/templates/postgres_exporter.service.j2
  48. 46
      site.yml

8
.ansible-lint

@ -0,0 +1,8 @@
---
skip_list:
- empty-lines
- colons
- commas
- braces

33
Makefile

@ -0,0 +1,33 @@
CLUSTER ?= sample
SSH_USER ?= $(USER)
SSH_KEY ?= $(USER)/.ssh/id_rsa
PROVISION_USER ?= provision
VAULT_FILE ?= .ansible_vault
ANSIBLE := ansible-playbook --user $(SSH_USER) --private-key $(SSH_KEY) --vault-password-file $(VAULT_FILE) --become --extra-vars "deploy_cluster=$(CLUSTER) provision_user=$(PROVISION_USER)"
ANSIBLE_CFG := ansible.cfg
HOSTS := inventory/$(CLUSTER)/hosts.ini
help: ## Display this help.
@awk 'BEGIN { \
FS = ":.*##"; \
printf "\nUsage:\n make \033[36m<target>\033[0m\n\nTargets:\n" \
} \
/^[a-zA-Z_-]+:.*?##/ { \
printf " \033[36m%-10s\033[0m %s\n", $$1, $$2 \
} \
END { \
print \
}' \
$(MAKEFILE_LIST)
install: provision ## Provision Greenplum cluster
provision: ## Provision Greenplum cluster
ANSIBLE_CONFIG=$(ANSIBLE_CFG) $(ANSIBLE) -i $(HOSTS) site.yml
users: ## Create extra users
ANSIBLE_CONFIG=$(ANSIBLE_CFG) $(ANSIBLE) -i $(HOSTS) add-users.yml

93
README.md

@ -0,0 +1,93 @@
# Deploy a Greenplum Cluster
![Greenplum Logo](https://s3.amazonaws.com/greenplum.org/wp-content/uploads/2017/08/11004213/logo-greenplum.png)
-----
## Description
This repository contains Ansible the following roles which could be used to
provision [Greenplum Database](https://greenplum.org/) cluster:
- [common](roles/common) configures the servers according to [official reccomendations](https://gpdb.docs.pivotal.io/6-7/install_guide/prep_os.html).
- [ntpd](roles/ntpd) installs ntp server with the [Russian time pools](https://www.pool.ntp.org/zone/ru).
- [greenplum](roles/greenplum) installs the main greenplum package.
- [greenplum-segment](roles/greenplum-segment) creates necessary directory tree for proper segment node work.
- [greenplum-master](roles/greenplum-master) configures a master node and initializes the cluster.
- [prometheus-exporter](roles/prometheus-exporter/) uses [postgres_exporter](https://github.com/wrouesnel/postgres_exporter) to provide database metrics.
## Requirements
- [Ansible](https://ansible.com/) v2.9.x.
- GNU Make.
## Hardware
It is possible to install Greenplum cluster on one server which will be used as
master and segment.
## Greenplum distributive and extensions
### Greenplum installation package
Greenplum RPM files should be placed into [files/rpm/](files/rpm/) directory. A
new Greenplum version can be downloaded from the
[official website](https://network.pivotal.io/products/pivotal-gpdb/#/releases/)
(it requires registration).
### Greenplum modules and extensions
All additional modules supported by default are listed on the
[Greenplum website](https://gpdb.docs.pivotal.io/6-4/ref_guide/modules/intro.html).
By default this Ansible role installs **and adds them to default database template**
the following extensions.
#### [hstore](https://gpdb.docs.pivotal.io/6-4/ref_guide/modules/hstore.html)
It provides a data type for storing sets of key/value pairs within a single
PostgreSQL value.
#### [PostGIS](https://gpdb.docs.pivotal.io/530/ref_guide/extensions/postGIS.html).
PostGIS is a spatial database extension for PostgreSQL that allows GIS
(Geographic Information Systems) objects to be stored in the database. The
Greenplum Database PostGIS extension includes support for GiST-based R-Tree
spatial indexes and functions for analysis and processing of GIS objects.
-----
## Usage
### 0. Make an inventory
[Sample inventory](inventory/sample/) may be used as a sample cluster manifest. To
make a new cluster just copy this directory to another one and adjust variables
and hosts IP addresses:
```sh
$ copy -r inventory/sample inventory/new-cluster
$ vim inventory/new_cluster/hosts.ini
$ vim inventory/new_cluster/group_vars/all/all.yml
```
-----
### 1. Make the SSH key for a new user and upload it to remote servers
```sh
$ ssh-keygen -C new_user@new_cluster -f inventory/new_cluster/files/ssh/new_user
$ make users PROVISION_USER=new_user
```
This command creates user on remote servers, configures sudoers file and
uploads the SSH key. All further Ansible playbooks will be executed under this
user.
### 2. Provision the Greenplum cluster
```sh
$ make provision CLUSTER=new_cluster SSH_USER=new_user SSH_KEY=inventory/new_cluster/files/ssh/new_user
```

27
add-users.yml

@ -0,0 +1,27 @@
---
- hosts: greenplum_cluster
become: yes
tasks:
- name: Create user to deploy greenplum cluster
user:
name: "{{ provision_user }}"
comment: User for configuring greenplum cluster
shell: /bin/bash
- name: Configure sudo for {{ provision_user }} user
copy:
dest: "/etc/sudoers.d/{{ provision_user }}"
content: "{{ provision_user }} ALL=(ALL) NOPASSWD: ALL"
- name: Upload SSH Key
authorized_key:
user: "{{ provision_user }}"
key: "{{ lookup('file', '../inventory/' ~ deploy_cluster ~ '/files/ssh/' ~ provision_user ~ '.pub') }}"
state: present
- name: Restart SSH service
service:
name: sshd
state: restarted

26
ansible.cfg

@ -0,0 +1,26 @@
[ssh_connection]
pipelining=True
ssh_args = -o ControlMaster=auto -o ControlPersist=30m -o ConnectionAttempts=100 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no
[defaults]
strategy_plugins = plugins/mitogen/ansible_mitogen/plugins/strategy
force_valid_group_names = ignore
force_color = 1
host_key_checking=False
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp
fact_caching_timeout = 7200
stdout_callback = default
display_skipped_hosts = no
library = ./library
callback_whitelist = profile_tasks
roles_path = roles:$VIRTUAL_ENV/usr/local/share/kubespray/roles:$VIRTUAL_ENV/usr/local/share/ansible/roles:/usr/share/kubespray/roles
deprecation_warnings=False
inventory_ignore_extensions = ~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo, .creds, .gpg
[inventory]
ignore_patterns = artifacts, credentials

1
files/pkg/postgis-2.5.4+pivotal.2.build.3-gp6-rhel7-x86_64.gppkg

@ -0,0 +1 @@
Sample package.

2
files/rpm/greenplum-db-6.7.0-rhel7-x86_64.rpm

@ -0,0 +1,2 @@
Greenplum packages can be found on the following page:
https://network.pivotal.io/products/pivotal-gpdb/#/releases/.

89
inventory/sample/files/ssh/gpadmin

@ -0,0 +1,89 @@
$ANSIBLE_VAULT;1.1;AES256
64386230616362663936343661373733396230393037623832376261306461393136386639356332
3035646262386138636235636130663038633135666563300a353033393164306639326564383131
62646333653339626466623935376463613437353363623238646363613134303936303462363765
3366643930666464350a343137376333373062366333613839323537373763386233356437376363
39653566616164346134306439633732343832643562633634396538373937626235383862643533
65333865626661643262323938383566613166613061643261643861663962633738646564316664
30306161663766656238376430653930386136386462643535373464623063383739386661636163
61393235326166306438373839313231616139373235303266343237346165643366333964333035
33666233303566383132386564393661313963616439623566353463623430646534303137656533
39383435376235316563306530313763353832643966373730623834666436343665653839343334
64343264663432303864366330373034653138333035363765366438326463643961323862656561
36343233373439316362666138373137383861363732336165623837303662366332393137663131
38636339663461373137663063356232353166323133616135346632333364653632623765313062
61313562303365336233386565336561663263653761303138643962633536333262333037323330
30633362333030633532316435653238303834336464636537623164336164383633346635323333
39363231303531333338383861663230326239356463336339323537346563653861373433323433
31333836633238656431343136623764363666303731353830393037613935373832353262386434
34336239386637313266373339333737616234663461306431306666303066666631333134663462
32613233366630386337656330626134316432333630373263643537633561303764663432343230
31373930663961643233303132393762623637636461396438643531376263633236656332393762
32383737633436323261363432346664633437646564643463636534393833383937356265346331
63643762353332316563613031643236343131323037356231316362623935643262653239313964
32396438353936323265393135333830386435613832613435616331383438336364373930313835
65663462356664353137353439323437643365653532643961313433663736343465313339373632
39336537373337643138303063383231653335613764383139373030656362353466356165393665
61666330646130666636303736393731666531396136373665663564383066356564636634356535
35646136313436643730343332643866643832353431366238613936623939343966646465393130
63636433633033306663633530643161613532303438636261303563376335336363613634396533
66323835393933653262376435383766656431306339626637356234366439653234633435323364
61313839313131373239646336346231326462376661346637386662613266313637656536323762
32623662633263366638376362626538643166656237646561313365303536303931633035323437
63333764336330386631373837383135373838373962393830326466636539663461363263376661
32616434626566343063393139333264326139393938386262333838313063353030386430326531
61383532373065376363303264316361633732326130363463333230333765363864633330373032
66396132643737326137623031626363366562663137386530393034303334306337393932356234
33633064373263623631346632383333653332363236663335393465633933626664336433653837
31353730363362393037393930303636626532366630306637393861356330636139356635343737
63393336336130303064613033653431366361396161313163646432353964663831363266333031
34396462356137333533386330333038666661326137396262393062313161616261383233613962
61323966336662373030373032333062313361353063343134666232333838346162613538643631
37316463346561383130383263633736313533616533653137353562373937623235346635363264
61366233353233643663666230303736666232366262616564356435333463383165363962623739
62373339343366626135653164343637326437343139313432373735383335373139643266326232
30643832376466363430353032373730306163383633383361383233626330613131383966663831
35613931646435303437343334656334393734316531396136633666623938376361336337616563
61353862353161343661343635366436383230323261666162363062353833353738653433613332
39636562393533356637616533323265636237316465386635386463356134653537623635626337
61316531376637323062396565326462653130396134376232333433626161646162346564323061
31636432616663633662323138313934653633346336626435393739353038636533393062613333
32383038326635363766373466626637363166623466343062316336333136313264333935373138
63613537623838376336623136313238383863316464666539326139356162633437356461353034
38363066343134653234643634393663666562633337363337326165393437646331393932636337
33653734613532656230346665643035366138323864396537653238383731363530666433376634
35346165346264363964383032336630663138346465323330363635326437636633306638636462
66306335663737663664336139626461303136343164636637663666363731373832353235363134
39343331636333373935626533323635366239656639636135356438626635323766383264346565
35643431396434346166386564396631643631356137356434656666396164306531666163653533
35613461343634633635323964613330663462656165346563333631616438333732626166336166
32663936313238336437306463616237366461336563346431363232356239363033623530633666
30623036623637623230333134666431303065616533393239633964626435336561316439633632
30386164346231616638653233663437356434663338393865393332643533393636663733336665
66613330393939653161303661656566653835643563613661353939316563313439663434393066
31333034303665623237356165313866323939356465313164366165316465376637656538373839
38653238643231316531613239343964653763383935656562333933303865393661343839363865
66313535356639393038356638356132616534656566333466616431633131336637613437613237
61383638633134663439373430613761626565393762333130373938643238373664306161363931
38383061393836646533396530626530646665393066393363366438333861333131613665656635
30633061303630666166326433663635663365346161316339653535333530343563396137313236
31633932303262396530373262393533333064616664666565303862616264623137356330663435
65623263303632333865363733333131383465326566643963613963613931326631386437653131
30616232356438613961373561653939343936616464323966306562613964316265623365303032
37316462323231366339663831336231313331636338633262636563343039666636646663633830
36306338333938353264643235643966373830353163313937313966336339376533633032633037
65303961616365656538386639366532373433366366396231646236613063366333643166363836
39396363383961386261653139346334623261383430313230663236633037333465613134636436
31306132366436333364333736663934356237663531353732653331353938306331366263623436
39666264353830383735623935323863333539653132316139373034356564363562323339353537
34373439663166366134373966323339643239353938623836353134316433363639346432386166
36303463333463333938353131316133346638336264633336646537383034373030353863656434
63623638353035653035633865666133646637356333636266653333313037316639373832323462
31346632376463313938653264366265333564303762313932333537396362333934656434373033
31653335383461333063316137623866313064373365363663633134613364646332663933613037
33333737313033393466303562653336656266636532646132306539373738323662393739386231
34663731626162636262636638353766633262373835363065313730393266376133323464656564
63303237343134393361313239316330663130333532656336396232666534326463343634653131
61356664653331393135336435396462363263303562366562336362666532333263646336346233
36363733383231353866636465356136396561306638336430636464326562383038326236353935
66306433613761663264

25
inventory/sample/files/ssh/gpadmin.pub

@ -0,0 +1,25 @@
$ANSIBLE_VAULT;1.1;AES256
33383862643130376538663834303564313838633431366333303564313737653563646263353163
6132323836356232333366633863333732303236353566630a313664623630366564393662313335
35386137636131623537303537343230343963346134633966343233383536663135366236383139
6464383539613563660a323335323532333961333235346663373130326130316564346331616234
30633266313539333165656634396161623463356163303435333035363937326135663762373366
38393539363463383862316335393363346465393237366133633261323037613033363663666635
32306435626161333332313037376634356338373433383936643838666130306530616438376264
32623162613930353238623936366535643535356632636137656137636563373030373535343063
38633731343630623633313932333462326266623965653533653563656166623464613138616139
31383065363864623163653036373630636136393137393432636665323737323633386564336362
31386138663863323538393964396137333537653637623838653633393935376361353963306166
35616633633838303865393161613161353433346235313936323733656466376537326533636232
63636163626634643033313332336638313135303830633433623330336162303031646331393238
37313965663939383736323338386561636535633235306538366364363430363162383034646634
35623332663934643135376336613039393831663135623561643336653263303861353466336132
30663630636331626633393039373434653631306464336464623765636331323965643037303364
37613436333939383434313133633562393037336265613863636430356331333861613065623739
64393063393964336138323838303332613836323636376637616534663865313830646132613933
31353262313136376637613438666439396138616266323765646230643937373331306561326630
65356664383134313164326633333839366430383662636263376161616433626539353130343138
30396535343364653738633164383138323066336636373932663432663065616432363934333362
32383937616539363139323432376333363065366261616363313336353862653634336365373062
37323839346336313030623266616465623462346134323965346162653866646561363934623235
35326465613564353234

89
inventory/sample/files/ssh/provision

@ -0,0 +1,89 @@
$ANSIBLE_VAULT;1.1;AES256
31373634383765343932613762623963663832646666623039386531616131633964616430363333
6138663133313931333861383031356338323535353162660a393661303362616138353062626333
31616263376362353538303466643563363038343034313333366336653832336263656636626362
6436633539653935370a616530343536343936356165326638393933653038613666393437663834
33663361376236356630663761393264646439643733303334663934353131356632376333646237
32636362613839313038303835373930323535336666613239363538633462643734363533336631
63323738353538653432326566633066656431303864626537636638333731303230656639653637
33323766363332313363643264616338623863356239623533613431343439383937636330333437
35363131623838313865623838356366663530633737396239376362336463383665323239356430
32343532396638623435366135393866653430323961626230656339383563306639356235633339
37633532376434653730663334656135336330346266313535636232336263633833373261646231
65303638393462373538343836356661366363373739616133323636396663393461653831356138
33303333313763383732343833343438333861343365316437613733363935626330383231653839
65323434333661316632303736366237633939393630323164383239646464663266396665323166
62653936656165616230393534393039653563343561633034353863383331346462653765363235
62306564346536393065653332643934313339366332643637613137623935643062666331653335
36393633353832383266333333333639663165386230333431336430333035333537346335383035
38623938313739313736373834393661393136383131623365393639653736353464346139653261
61646236363438336436326335316161373834333333313530326661333532653639303663626264
65396165383365313364636536646261323638613262303462643539646338336231663663636165
62303361656161366533613437323938663931623633623461373766353130653137666639656138
66646664313037623932396637306533386466383162646631393739623538393134333366666435
65376332323533313130303038663030323035656638623737626232613335623632396430646531
32626461366438336561393436643236656636313833623934643761643165363833303338386133
39383131616334356234383333303234333166326564396530643464643935393339343135366439
66653530333761333632386230313730383364643735306435303462363336366531313538306662
65643830393634663436386665633264643633663830336231653264356430326434626534306161
36626165383638653639393437353833303764373735663731323534393062373137323962313737
62363039613234616538373731623835663139616264373238383866373465343639353832643135
63666264396333353330346364623061666433643338656266306261613430636565393437346430
34633731643937666339613865363131636134623338613639363764333761353361353233383934
34383136303061313064663630343363373637666338333033393933363063313735326332343962
64313433616335626330343133316635396532373331623332666463623266366637326139643731
38626634303363383532303438386665333864623330353366356236353530386461643939363430
37366364656462393237623163336537643432313937343831396161336264386437643130616563
61646365383630623532663833363838393961303165656437653564383732386531393364316565
66666363383736666234666436623765623463316635653936613134303232306463633039326131
37333766356166323465666264613166633936663838306536616333386366643062343066396231
65653430666531303264316638656630326134346563643561386438366165656535316139356439
63373864633961646534356139386363666138626362666435353130333935623964323337396361
62653362636562346134376132613362383839643635353233393862663761616439363037366335
65303565623139666337363266643033366536366539323438613364633566306339383833333634
62336366383965353731393536366362376638343033383638663366396261396336313932613334
65626330373063666563353061663337336366613731376661613665646538653934633339333833
38313734363037336262383038636463356361626238633332386439363436323961366161643163
34616161663364346166386135316161323466323233356638643238393762383261303562666466
37636263303966326234373363363933373631613535623535323638383561643738336639373864
30326162313165313039616166356365623561643862333763366363653132313861313334636665
30386234346165636363393230346166666334616231633634393130373963623861643339643132
35303835353031393964633238623666666366636561326264326231343065626663393632366564
63643465616132356633373439653664333165643366306163633863333163663364663736343039
33343238333630363334663730623265353339613362393830393138336437633561643162626232
32623633363836333133303066383732396466363334653864643063386433623236393335643761
62343931343533613030623435373766666364383536343836396233366131303064376265633563
37623633626230613739623065386135393632323263383463353639393730663563663961616462
37316263656233383465363065613836663261346133333838326566306337633735306338316234
37333334333462616639643839663831363863313837616464376634613132326631656464393439
36653962613866626161383734323865363632393430616435373366373838643762623534303433
34353235646364313434633637373138306162333435353139613839633835626432383334646235
63613964616430666337636363323133636632376538313733323863396265393762373836346366
62393239333030313333383862383333643135646461363461663763323061616165623236663837
65666461386536393763366631643338323336393936363330656361613331303465363731393135
66396262643165653862646361393136643662626162666563356363353030383230396436326133
36393762323937646662313130313433376437383863333137326139656337353332393831336333
38663662356239396665653436613432363265353638393461643633623765616132633334343335
39343830313062303263363061666635646133353639396335646632333830383564613636616161
62363936306232633333393434616637363239656662316336653963323165343464343939333936
38386230363034393637353864346438333965646536626532323261636566616162383330343831
35336430373162383962653735373364356664313537616132323066323031336664376636653966
38356361626161303561313335623433623539326236366465663662656364663833633138303239
33333733326264336565323730313139363739373664613236303939323161653734626136343265
32626565356130363965343535393933663566313131626532333332636565663335643762386262
35346566376639633133303665376233393962386562386134303833396235376264373265623261
65323531633932373334386437623661383238616366623936363130336638303437393630303735
66306465316436333434356631643161613633366334353137336561343234666230633336316364
66393461623232393333373561653033653333393438373965633862363335396433366664373966
34333532396132653234623535363961633764643662656233383332643165393863383338343334
33626132626638373537643961653461396362323731663438353735353237333833623735643466
61346638663064623737363064366634363237363262623962356133303939346339393165336636
64343266626363643465613537326464656233613131323035636333643166323264623965323334
65383130363566376162376534616661343234613666636263666166313864376665356438616266
30386430313363613438386532643337383261663361616436313539353139313035376236663735
35646331396232626565623730336231666465383866323466396539653866313930396630633639
31343135393533663462303463663039356632323132326530353331363634333130323834646330
63633537653963663033643936626263376661623164356532613164656264623963616265356635
66363934656363346530653932633236393265313937313130393533633631313439303363633663
38383538663564363761353162366435333637353565303431323033373261383563303061623136
32346532646534323530

25
inventory/sample/files/ssh/provision.pub

@ -0,0 +1,25 @@
$ANSIBLE_VAULT;1.1;AES256
31616466353563373530653730633765303565303032656137383732333137396366626437336136
3130316365633839343962643761306433336463346366660a313332633836356464356562313561
31323930656239386539346539616561646433623835633830363961363933663931386665636539
3964306531623661360a646464613630383263376231623566386339386162343834383463363564
35393939636639343230653630663033366631386565383131663134326266353066623061363766
65663363366638643761313339303635626235393261633937653934633764346665653335653835
39313330303737643662366230626562643031316638303032333034363238306432396231346531
35643036653631663830666564643030363839626333333431626466356232343066613731616133
64316330663439363366323732363136303561326333353439346434383332316261616263303232
32346438343332303932376564383263396237326436646135636430633761626538323735366664
61656138383532666263656336396464666232663735623765623830613830316436376462653034
64326436303933333639616537666561376464396633333539326466333230636162393162316633
30613864626332316363613539616330643665303030343762323465326235643336316539366130
64393733623730343865653162393330383761326666356339393162653732376161666131623331
36633866356361386630336633356534303837393935356632333738653636326465376430303636
63656138356238366438323332323263623133376435633662323261363336333136313732376433
66383739386566646238316439316131323364613337313734623831623932376132346538366665
32643365303262643331653664383436636636633934336636636166306436623039376566646437
66373731393438366430336632326336633965653833653566306334303333356136336234623031
65303166313936343530313932313034306463646530633235303265666136636632393564366536
36643264643337323139633563366663363735393664396634386538643963383439656365373237
66383435646534303739393462316334646566396436623465663064333665333363393237383339
38323464376538656137663839313839333266346238643438313931303961333234366631333765
30663335313738623365

68
inventory/sample/group_vars/all/all.yml

@ -0,0 +1,68 @@
---
timezone: UTC
greenplum_group: gpadmin
greenplum_user: gpadmin
greenplum_user_id: 10000
greenplum_user_profile_file: "~{{ greenplum_user }}/.bashrc"
greenplum_sudo: false
greenplum_master_port: 5432
greenplum_src_directory: /opt/src
greenplum_data_directory: /opt/data
greenplum_master_directory: "{{ greenplum_data_directory }}/master"
greenplum_postgis_databases:
- postgres
- template1 # enable PostGIS for all new databases by default
greenplum_extensions:
- name: hstore
databases:
- template1 # enable hstore extencion for all new databases by default
greenplum_config_directory: /opt/gpconfig
# Maximum log file segments between automatic WAL checkpoints.
greenplum_check_point_segments: 8
#### Base number by which primary segment port numbers are calculated.
greenplum_port_base: 6000
#### Naming convention for utility-generated data directories.
greenplum_seg_prefix: gpseg
postgres_exporter_enabled: true
postgres_exporter_host: "127.0.0.1:5432"
postgres_exporter_database: "postgres"
postgres_exporter_user: gpmon
postgres_exporter_password: password
# - { contype: host|local, source: ::1, databases: "postgres,db1,db2", users: "admin,dev,qa", method: md5|ident|password|peer|trust|... }
greenplum_trusted_hosts:
- contype: host
source: 172.22.0.0/16
databases: all
users: dev
method: md5
- contype: host
source: 127.0.0.1/32
databases: all
users: "{{ postgres_exporter_user }}"
method: md5
# - { name: user, password: <password>, superuser: true|false, groups: [group1, group2] }
greenplum_users:
- name: dev
superuser: true
password: password
- name: "{{ postgres_exporter_user }}"
superuser: true
password: "{{ postgres_exporter_password }}"

10
inventory/sample/hosts.ini

@ -0,0 +1,10 @@
[all]
greenplum_master ansible_host=10.2.3.4 greenplum_hostname=greenplum-cluster
[greenplum_segments]
greenplum_master
[greenplum_cluster]
greenplum_master

8
roles/common/defaults/main.yml

@ -0,0 +1,8 @@
---
greenplum_group: gpadmin
greenplum_user: gpadmin
greenplum_user_id: 10000
greenplum_sudo: false

12
roles/common/handlers/main.yml

@ -0,0 +1,12 @@
---
- name: enable rc.local
ansible.builtin.file:
path: /etc/rc.local
mode: 0744
- name: restart sshd
ansible.builtin.service:
name: sshd
state: restarted

11
roles/common/tasks/dependencies.yml

@ -0,0 +1,11 @@
---
- name: Install Greenplum dependencies and common packages
ansible.builtin.package:
state: present
name:
- xerces-c-devel
- python-psycopg2
- python-ipaddress
- libzstd

65
roles/common/tasks/disks.yml

@ -0,0 +1,65 @@
---
#
# XFS is the preferred data storage file system on Linux platforms. Use the
# mount command with the following recommended XFS mount options for RHEL and
# CentOS systems:
#
# rw,nodev,noatime,nobarrier,inode64
#
# The nobarrier option is not supported on Ubuntu systems. Use only the
# options:
#
# rw,nodev,noatime,inode64
#
- name: disks | Set mount options for /
ansible.builtin.mount:
path: "/"
src: "UUID={{ ansible_mounts | json_query('[?mount == `/`] | [0].uuid') }}"
fstype: "xfs"
opts: "rw,nodev,noatime,nobarrier,inode64"
state: "present"
- name: disks | Get all block devices
ansible.builtin.set_fact:
disks: "{{ disks|default([]) + [item.key] }}"
with_dict: "{{ ansible_devices }}"
when: item.key.startswith('sda')
#
# Each disk device file should have a read-ahead (blockdev) value of 16384.
#
- name: disks | Adjust block devices read-ahead settings
ansible.builtin.shell: "/sbin/blockdev --setra 16384 /dev/{{ item }}"
with_items: "{{ disks | default([]) }}"
tags: skip_ansible_lint
- name: disks | Add blockdev command to rc.local file
ansible.builtin.lineinfile:
path: /etc/rc.local
line: "/sbin/blockdev --setra 16384 /dev/{{ item }}"
with_items: "{{ disks | default([]) }}"
notify: enable rc.local
#
# The Linux disk I/O scheduler for disk access supports different policies,
# such as CFQ, AS, and deadline.
#
# The deadline scheduler option is recommended. To specify a scheduler
# until the next system reboot, run the following:
#
- name: disks | Adjust block devices scheduler
ansible.builtin.shell: "echo deadline > /sys/block/{{ item }}/queue/scheduler"
tags: skip_ansible_lint
with_items: "{{ disks | default([]) }}"
- name: disks | Adjust block devices scheduler during OS boot process
ansible.builtin.lineinfile:
path: /etc/rc.local
line: "echo deadline > /sys/block/{{ item }}/queue/scheduler"
with_items: "{{ disks | default([]) }}"
notify: enable rc.local

9
roles/common/tasks/firewall.yml

@ -0,0 +1,9 @@
---
- name: Stop firewalld service
ansible.builtin.service:
name: firewalld
state: stopped
enabled: false
when: '"firewalld" in ansible_facts.services'

24
roles/common/tasks/kernel.yml

@ -0,0 +1,24 @@
---
#
# Disable Transparent Huge Pages (THP) as it degrades Greenplum Database
# performance. RHEL 6.0 or higher enables THP by default.
#
- name: kernel | Get current THP settings
ansible.builtin.shell: cat /sys/kernel/mm/*transparent_hugepage/enabled
changed_when: false
register: current_thp_mode
- name: kernel | Show current THP settings
ansible.builtin.debug: var=current_thp_mode.stdout verbosity=2
- name: kernel | Disable Transparent Huge Pages
ansible.builtin.shell: "echo never > /sys/kernel/mm/transparent_hugepage/enabled"
tags: skip_ansible_lint
- name: kernel | Disable Transparent Huge Pages by default
ansible.builtin.shell: 'grubby --update-kernel=ALL --args="transparent_hugepage=never"'
when: '"[never]" not in current_thp_mode.stdout'
tags: skip_ansible_lint

25
roles/common/tasks/limits.yml

@ -0,0 +1,25 @@
---
#
# For Red Hat Enterprise Linux (RHEL) and CentOS systems, parameter values
# in the /etc/security/limits.d/90-nproc.conf file (RHEL/CentOS 6) or
# /etc/security/limits.d/20-nproc.conf file (RHEL/CentOS 7) override the values
# in the limits.conf file. Ensure that any parameters in the override file are
# set to the required value.
#
- name: limits | Adjust PAM limits
community.general.pam_limits:
domain: '*'
limit_type: "{{ item.type }}"
limit_item: "{{ item.name }}"
value: "{{ item.value }}"
dest: "/etc/security/limits.d/20-nproc.conf"
loop_control:
label: "* {{ item.type }} {{ item.name }} {{ item.value }}"
loop:
- { type: 'soft', name: 'nofile', value: '524288' }
- { type: 'hard', name: 'nofile', value: '524288' }
- { type: 'soft', name: 'nproc', value: '131072' }
- { type: 'hard', name: 'nproc', value: '131072' }

15
roles/common/tasks/main.yml

@ -0,0 +1,15 @@
---
- name: Collect information about services
ansible.builtin.service_facts:
- include: 'dependencies.yml'
- include: 'sysctl.yml'
- include: 'limits.yml'
- include: 'kernel.yml'
- include: 'disks.yml'
- include: 'timezone.yml'
- include: 'users.yml'
- include: 'firewall.yml'
- include: 'ssh.yml'

55
roles/common/tasks/ssh.yml

@ -0,0 +1,55 @@
---
- name: Add current server IP addresses to /etc/hosts
ansible.builtin.lineinfile:
path: /etc/hosts
line: "127.0.0.1 {{ hostvars[item]['greenplum_hostname'] }} # {{ item }}"
with_items: "{{ groups['greenplum_cluster'] }}"
when: groups['greenplum_cluster'] | length == 1
- name: Add all Greenplum IP addresses to /etc/hosts
ansible.builtin.lineinfile:
path: /etc/hosts
line: >
"{{ hostvars[item]['ip_address'] if 'ip_address' in hostvars[item] else hostvars[item]['ansible_host'] }} {{ hostvars[item]['greenplum_hostname'] }}
# {{ item }}"
with_items: "{{ groups['greenplum_cluster'] }}"
when: item != inventory_hostname
- name: ssh | Set proper MaxStartups value
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^MaxStartups'
line: 'MaxStartups 10:30:200'
notify: restart sshd
- name: ssh | Set proper MaxSessions value
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^MaxSessions'
line: 'MaxSessions 200'
notify: restart sshd
- name: Add public Greenplum SSH Key to authorized_key list
ansible.posix.authorized_key:
user: "{{ greenplum_user }}"
key: "{{ lookup('file', 'inventory/' ~ deploy_cluster ~ '/files/ssh/' ~ greenplum_user ~ '.pub') }}"
state: present
notify: restart sshd
- name: Upload private Greenplum SSH Key
ansible.builtin.copy:
dest: "~{{ greenplum_user }}/.ssh/id_rsa"
src: "{{ 'inventory/' ~ deploy_cluster ~ '/files/ssh/' ~ greenplum_user }}"
owner: "{{ greenplum_user }}"
group: "{{ greenplum_group }}"
mode: 0600
- name: Upload public Greenplum SSH Key
ansible.builtin.copy:
dest: "~{{ greenplum_user }}/.ssh/id_rsa.pub"
src: "{{ 'inventory/' ~ deploy_cluster ~ '/files/ssh/' ~ greenplum_user ~ '.pub' }}"
owner: "{{ greenplum_user }}"
group: "{{ greenplum_group }}"
mode: 0600

143
roles/common/tasks/sysctl.yml

@ -0,0 +1,143 @@
---
- name: sysctl | Get PAGE_SIZE
ansible.builtin.shell: getconf PAGE_SIZE
register: page_size
changed_when: false
tags: skip_ansible_lint
- name: Show PAGE_SIZE
ansible.builtin.debug: var=page_size.stdout verbosity=2
- name: sysctl | Get _PHYS_PAGES
ansible.builtin.shell: getconf _PHYS_PAGES
register: phys_pages
changed_when: false
tags: skip_ansible_lint
- name: sysctl | Calculate optimal kernel_shmall value
ansible.builtin.set_fact:
kernel_shmall: "{{ (phys_pages.stdout|int / 2) | int }}" # kernel.shmall = _PHYS_PAGES / 2 # See Shared Memory Pages
- name: Show kernel_shmall
ansible.builtin.debug: var=kernel_shmall verbosity=2
- name: sysctl | Calculate optimal kernel_shmmax value
ansible.builtin.set_fact:
kernel_shmmax: "{{ (kernel_shmall|int * page_size.stdout|int) }}" # kernel.shmmax = kernel.shmall * PAGE_SIZE
- name: Show kernel_shmmax
ansible.builtin.debug: var="{{ kernel_shmmax }}" verbosity=2
- name: sysctl | Adjust sysctl settings
ansible.builtin.sysctl:
name: "{{ item.option }}"
value: "{{ item.value }}"
state: present
reload: true
loop_control:
label: "{{ item.option }} = {{ item.value }}"
loop:
- { option: 'kernel.shmall', value: '{{ kernel_shmall }}' }
- { option: 'kernel.shmmax', value: '{{ kernel_shmmax }}' }
- { option: 'kernel.shmmni', value: '4096' }
- { option: 'kernel.sem', value: '500 2048000 200 4096' }
- { option: 'kernel.sysrq', value: '1' }
- { option: 'kernel.core_uses_pid', value: '1' }
- { option: 'kernel.msgmnb', value: '65536' }
- { option: 'kernel.msgmax', value: '65536' }
- { option: 'kernel.msgmni', value: '2048' }
- { option: 'net.ipv4.tcp_syncookies', value: '1' }
- { option: 'net.ipv4.conf.default.accept_source_route', value: '0' }
- { option: 'net.ipv4.tcp_max_syn_backlog', value: '4096' }
- { option: 'net.ipv4.conf.all.arp_filter', value: '1' }
- { option: 'net.core.netdev_max_backlog', value: '10000' }
- { option: 'net.core.rmem_max', value: '2097152' }
- { option: 'net.core.wmem_max', value: '2097152' }
- { option: 'vm.swappiness', value: '10' }
- { option: 'vm.zone_reclaim_mode', value: '0' }
- { option: 'vm.dirty_expire_centisecs', value: '500' }
- { option: 'vm.dirty_writeback_centisecs', value: '100' }
# The vm.overcommit_memory Linux kernel parameter is used by the OS to
# determine how much memory can be allocated to processes. For Greenplum
# Database, this parameter should always be set to 2.
- { option: 'vm.overcommit_memory', value: '2' }
# vm.overcommit_ratio is the percent of RAM that is used for application
# processes and the remainder is reserved for the operating system. The default
# is 50 on Red Hat Enterprise Linux.
- { option: 'vm.overcommit_ratio', value: '95' }
# To avoid port conflicts between Greenplum Database and other applications
# during Greenplum initialization, make a note of the port range specified by
# the operating system parameter net.ipv4.ip_local_port_range. When
# initializing Greenplum using the gpinitsystem cluster configuration file, do
# not specify Greenplum Database ports in that range. For example, if
# net.ipv4.ip_local_port_range = 10000 65535, set the Greenplum Database base
# port numbers to these values.
#
# PORT_BASE = 6000
# MIRROR_PORT_BASE = 7000
#
- { option: 'net.ipv4.ip_local_port_range', value: '10000 65535' }
# Increase vm.min_free_kbytes to ensure PF_MEMALLOC requests from network
# and storage drivers are easily satisfied. This is especially critical on
# systems with large amounts of system memory. The default value is often far
# too low on these systems.
#
# Do not set vm.min_free_kbytes to higher than 5% of system memory as doing
# so might cause out of memory conditions.
#
- name: sysctl | Calculate optimal vm.min_free_kbytes value
ansible.builtin.set_fact:
vm_min_free_kbytes: "{{ (ansible_memtotal_mb|int * 1024 * 0.3) | int }}"
- name: Show vm_min_free_kbytes
ansible.builtin.debug: var=vm_min_free_kbytes verbosity=2
# For host systems with more than 64GB of memory, these settings are recommended:
#
# vm.dirty_background_ratio = 0
# vm.dirty_ratio = 0
# vm.dirty_background_bytes = 1610612736 # 1.5GB
# vm.dirty_bytes = 4294967296 # 4GB
#
- name: sysctl | Adjust memory settings on hosts with 64+ Gb RAM
ansible.builtin.sysctl:
name: "{{ item.option }}"
value: "{{ item.value }}"
state: present
reload: true
loop_control:
label: "{{ item.option }} = {{ item.value }}"
loop:
- { option: 'vm.dirty_background_ratio', value: '0' }
- { option: 'vm.dirty_ratio', value: '0' }
- { option: 'vm.dirty_background_bytes', value: '1610612736' }
- { option: 'vm.dirty_bytes', value: '4294967296' }
- { option: 'vm.min_free_kbytes', value: '{{ vm_min_free_kbytes }}' }
when: ansible_memtotal_mb >= 65536
# For host systems with 64GB of memory or less, remove
# vm.dirty_background_bytes and vm.dirty_bytes and set the two ratio parameters
# to these values:
#
# vm.dirty_background_ratio = 3
# vm.dirty_ratio = 10
#
- name: sysctl | Adjust memory settings on hosts with <64 Gb RAM
ansible.builtin.sysctl:
name: "{{ item.option }}"
value: "{{ item.value }}"
state: present
reload: true
loop_control:
label: "{{ item.option }} = {{ item.value }}"
loop:
- { option: 'vm.dirty_background_ratio', value: '3' }
- { option: 'vm.dirty_ratio', value: '10' }
- { option: 'vm.min_free_kbytes', value: '{{ vm_min_free_kbytes }}' }
when: ansible_memtotal_mb < 65536

6
roles/common/tasks/timezone.yml

@ -0,0 +1,6 @@
---
- name: Set timezone to {{ timezone }}
community.general.timezone:
name: "{{ timezone }}"

25
roles/common/tasks/users.yml

@ -0,0 +1,25 @@
---
- name: users | Create Greenplum admin group
ansible.builtin.group:
name: "{{ greenplum_group }}"
gid: "{{ greenplum_user_id }}"
state: present
system: true # Prevent IPC connections removing when user logs out.
- name: users | Create Greenplum admin user
ansible.builtin.user:
name: "{{ greenplum_user }}"
uid: "{{ greenplum_user_id }}"
group: "{{ greenplum_group }}"
comment: Greenplum admin user
system: true # Prevent IPC connections removing when user logs out.
shell: /bin/bash
- name: users | Configure sudo for Greenplum admin user
ansible.builtin.copy:
dest: "/etc/sudoers.d/{{ greenplum_user }}"
content: "{{ greenplum_user }} ALL=(ALL) NOPASSWD: ALL"
mode: 0644
when: greenplum_sudo

16
roles/greenplum-master/defaults/main.yml

@ -0,0 +1,16 @@
---
greenplum_src_directory: /opt/src
greenplum_data_directory: /opt/data
greenplum_config_directory: /opt/gpconfig
greenplum_postgis_databases:
- template1 # enable PostGIS for all new databases by default
# All supported extensions are listed here: https://gpdb.docs.pivotal.io/6-4/ref_guide/modules/intro.html
greenplum_extensions:
- name: hstore
databases:
- template1 # enable hstore extencion for all new databases by default

39
roles/greenplum-master/handlers/main.yml

@ -0,0 +1,39 @@
---
- name: enable greenplum service
ansible.builtin.systemd:
name: greenplum
state: started
enabled: true
daemon_reload: true
- name: start greenplum service
ansible.builtin.systemd:
name: greenplum
state: started
enabled: true
daemon_reload: true
- name: restart greenplum service
ansible.builtin.systemd:
name: greenplum
state: restarted
enabled: true
daemon_reload: true
- name: stop greenplum service
ansible.builtin.systemd:
name: greenplum
state: stopped
enabled: true
daemon_reload: true
- name: update greenplum configuration
become: true
become_user: "{{ greenplum_user }}"
ansible.builtin.shell: >
export MASTER_DATA_DIRECTORY={{ greenplum_master_directory }}/{{ greenplum_seg_prefix }}-1;
source /usr/local/greenplum-db/greenplum_path.sh &&
gpstop -u -a
tags: skip_ansible_lint

93
roles/greenplum-master/tasks/extensions.yml

@ -0,0 +1,93 @@
---
- name: greenplum master | Upload Greenplum extensions
ansible.builtin.copy:
src: "{{ item }}"
dest: "{{ greenplum_src_directory }}"
mode: 0644
with_fileglob:
- "files/pkg/*"
- name: greenplum master | Install Greenplum extensions
become: true
become_user: "{{ greenplum_user }}"
ansible.builtin.shell: >
export MASTER_DATA_DIRECTORY={{ greenplum_master_directory }}/{{ greenplum_seg_prefix }}-1;
source /usr/local/greenplum-db/greenplum_path.sh;
installed_packages=$(gppkg --query --all \
| tail -n +2 \
| awk '{printf NR==1?$0:"\\|"$0}');
if [ -z "$installed_packages" ]; then
mapfile -t packages < <(\ls -1 {{ greenplum_src_directory }}/*.gppkg)
else
mapfile -t packages < <(\ls -1 {{ greenplum_src_directory }}/*.gppkg \
| grep -v "$installed_packages");
fi
echo "${packages[@]}"
for pkg in "${packages[@]}"; do
gppkg -a -i "$pkg"
done
args:
executable: /bin/bash
register: gppkg_log
changed_when: "'Completed local installation' in gppkg_log.stdout"
failed_when: false
tags: skip_ansible_lint
- name: greenplum master | Show gppkg log
ansible.builtin.debug: var=gppkg_log verbosity=2
- name: greenplum master | Get all Greenplum databases
become: true
become_user: "{{ greenplum_user }}"
community.general.postgresql_info:
db: template1
login_host: "127.0.0.1"
login_user: "{{ greenplum_user }}"
filter:
- "databases"
register: greenplum_databases
- name: greenplum master | Enable PostGIS for databases
become: true
become_user: "{{ greenplum_user }}"
ansible.builtin.shell: >
export MASTER_DATA_DIRECTORY={{ greenplum_master_directory }}/{{ greenplum_seg_prefix }}-1;
source /usr/local/greenplum-db/greenplum_path.sh;
psql {{ item.key }} -c '\dv' | grep -q geography;
if [ "$?" -ne 0 ]; then
/bin/bash $GPHOME/share/postgresql/contrib/postgis*/postgis_manager.sh "{{ item.key }}" install;
fi
args:
executable: /bin/bash
register: postgis_install_log
changed_when:
- 'postgis_install_log.stdout_lines | length > 0'
- 'postgis_install_log.stdout_lines | last == "ANALYZE"'
tags: skip_ansible_lint
when: item.key in greenplum_postgis_databases
loop_control:
label: "{{ item.key }}"
loop: "{{ lookup('dict', greenplum_databases.databases) }}"
- name: greenplum master | Show postgis installation log
ansible.builtin.debug: var=postgis_install_log verbosity=2
- name: greenplum master | Enable Greenplum extensions
become: true
become_user: "{{ greenplum_user }}"
community.general.postgresql_ext:
login_host: "127.0.0.1"
login_user: "{{ greenplum_user }}"
name: "{{ item.0.name }}"
db: "{{ item.1 }}"
loop_control:
label: "{{ item.1 }}/{{ item.0.name }}"
loop: "{{ greenplum_extensions | subelements('databases') }}"

106
roles/greenplum-master/tasks/init.yml

@ -0,0 +1,106 @@
---
- name: greenplum master | Make directory to store data
ansible.builtin.file:
path: "{{ greenplum_data_directory }}/master"
owner: "{{ greenplum_user }}"
group: "{{ greenplum_group }}"
state: directory
recurse: true
- name: greenplum master | Make directory to save configuration files
ansible.builtin.file:
path: "{{ greenplum_config_directory }}"
owner: "{{ greenplum_user }}"
group: "{{ greenplum_group }}"
state: directory
recurse: true
- name: greenplum master | Make Greenplum configuration file
ansible.builtin.template:
src: gpinitsystem_config.j2
dest: "{{ greenplum_config_directory }}/gpinitsystem_config"
owner: "{{ greenplum_user }}"
group: "{{ greenplum_group }}"
mode: 0644
register: greenplum_configuration
- name: greenplum master | Make a hosts file
ansible.builtin.template:
src: hostfile_gpinitsystem.j2
dest: "{{ greenplum_config_directory }}/hostfile_gpinitsystem"
owner: "{{ greenplum_user }}"
group: "{{ greenplum_group }}"
mode: 0644
- name: greenplum master | Exchange ssh keys between all Greenplum nodes
become: true
become_user: "{{ greenplum_user }}"
ansible.builtin.shell: >
export MASTER_DATA_DIRECTORY={{ greenplum_master_directory }}/{{ greenplum_seg_prefix }}-1;
source /usr/local/greenplum-db/greenplum_path.sh &&
gpssh-exkeys -f "{{ greenplum_config_directory }}/hostfile_gpinitsystem"
changed_when: false
failed_when: false
tags: skip_ansible_lint
- name: greenplum master | Check current Greenplum timezone
become: true
become_user: "{{ greenplum_user }}"
ansible.builtin.shell: >
export MASTER_DATA_DIRECTORY={{ greenplum_master_directory }}/{{ greenplum_seg_prefix }}-1;
source /usr/local/greenplum-db/greenplum_path.sh &&
gpconfig -s TimeZone | grep -E 'Master|Segment' | cut -d : -f 2 | sort -u | grep -v "{{ timezone }}"
register: greenplum_timezone
failed_when: false
changed_when: greenplum_timezone.stdout_lines | length > 0
tags: skip_ansible_lint
- name: greenplum master | Set Greenplum timezone to {{ timezone }}
become: true
become_user: "{{ greenplum_user }}"
ansible.builtin.shell: >
export MASTER_DATA_DIRECTORY={{ greenplum_master_directory }}/{{ greenplum_seg_prefix }}-1;
source /usr/local/greenplum-db/greenplum_path.sh &&
gpconfig -c TimeZone -v "{{ timezone }}"
when: greenplum_timezone.stdout_lines | length > 0
notify: restart greenplum service
tags: skip_ansible_lint
- name: greenplum master | Check Greenplum cluster status
become: true
become_user: "{{ greenplum_user }}"
ansible.builtin.shell: >
export MASTER_DATA_DIRECTORY={{ greenplum_master_directory }}/{{ greenplum_seg_prefix }}-1;
source /usr/local/greenplum-db/greenplum_path.sh &&
gpstate -s
ignore_errors: true
register: gpstate
changed_when: false
failed_when: false
tags: skip_ansible_lint
- name: greenplum master | Initialize Greenplum database cluster
become: true
become_user: "{{ greenplum_user }}"
ansible.builtin.shell: >
source /usr/local/greenplum-db/greenplum_path.sh &&
gpinitsystem -a
-c {{ greenplum_config_directory }}/gpinitsystem_config
-h {{ greenplum_config_directory }}/hostfile_gpinitsystem
register: gpinitsystem_log
tags: skip_ansible_lint
when: gpstate.rc != 0
failed_when:
- '"Greenplum Database instance successfully created" not in gpinitsystem_log.stdout'
- name: greenplum master | Add Greenplum master directory to user profile
ansible.builtin.lineinfile:
path: "{{ greenplum_user_profile_file }}"
line: "export MASTER_DATA_DIRECTORY={{ greenplum_master_directory }}/{{ greenplum_seg_prefix }}-1"
- name: greenplum master | Adjust LD_PRELOAD for ps command
ansible.builtin.lineinfile:
path: "{{ greenplum_user_profile_file }}"
line: "export LD_PRELOAD=/lib64/libz.so.1 ps"

46
roles/greenplum-master/tasks/main.yml

@ -0,0 +1,46 @@
---
# Initialize Greenplum cluster
- include: init.yml
- name: greenplum master | Create systemd service
ansible.builtin.template:
src: greenplum.service.j2
dest: /etc/systemd/system/greenplum.service
owner: root
group: root
mode: 0644
register: greenplum_service
- name: greenplum master | Stop greenplum started via cli and start it via systemd service
when: greenplum_service.changed or gpstate.rc != 0
block:
- name: greenplum master | Stop Greenplum
become: true
become_user: "{{ greenplum_user }}"
ansible.builtin.shell: >
source {{ greenplum_user_profile_file }} &&
gpstop -a
tags: skip_ansible_lint
- name: greenplum master | Start Greenplum service
ansible.builtin.systemd:
name: greenplum
state: started
enabled: true
daemon_reload: true
# Greenplum database extensions (e.g. PostGIS)
- include: 'extensions.yml'
# Users, permissions, pg_hba.conf
- include: 'roles.yml'
- name: greenplum master | Reload Greenplum configuration
ansible.builtin.debug:
msg: "Greenplum configuration has been changed. Require restart"
when:
- gpstate.rc != 0
- greenplum_configuration.changed
notify: update greenplum configuration

29
roles/greenplum-master/tasks/roles.yml

@ -0,0 +1,29 @@
---
- name: greenplum master | Create Greenplum users
community.general.postgresql_user:
db: template1
login_host: "127.0.0.1"
login_user: "{{ greenplum_user }}"
name: "{{ item.name }}"
password: "{{ item.password }}"
groups: "{{ item.groups | default(omit) }}"
role_attr_flags: "{{ 'SUPERUSER' if item.superuser else '' }}"
state: present
loop: "{{ greenplum_users }}"
loop_control:
label: "{{ item.name }}"
notify: update greenplum configuration
- name: greenplum master | Adjust pg_hba.conf
community.general.postgresql_pg_hba:
dest: "{{ greenplum_master_directory }}/{{ greenplum_seg_prefix }}-1/pg_hba.conf"
contype: "{{ item.contype }}"
source: "{{ item.source }}"
databases: "{{ item.databases }}"
users: "{{ item.users }}"
method: "{{ item.method }}"
state: present
loop: "{{ greenplum_trusted_hosts }}"
notify: update greenplum configuration

71
roles/greenplum-master/templates/gpinitsystem_config.j2

@ -0,0 +1,71 @@
# FILE NAME: gpinitsystem_config
# {{ ansible_managed }}
# Configuration file needed by the gpinitsystem
################################################
#### REQUIRED PARAMETERS
################################################
#### Name of this Greenplum system enclosed in quotes.
ARRAY_NAME="{{ deploy_cluster | upper }} Greenplum Data Platform"
#### Naming convention for utility-generated data directories.
SEG_PREFIX={{ greenplum_seg_prefix }}
#### Base number by which primary segment port numbers
#### are calculated.
PORT_BASE={{ greenplum_port_base }}
#### File system location(s) where primary segment data directories
#### will be created. The number of locations in the list dictate
#### the number of primary segments that will get created per
#### physical host (if multiple addresses for a host are listed in
#### the hostfile, the number of segments will be spread evenly across
#### the specified interface addresses).
declare -a DATA_DIRECTORY=({% for _host in groups['greenplum_segments'] %}{{ greenplum_data_directory }}/primary {% endfor %})
#### OS-configured hostname or IP address of the master host.
MASTER_HOSTNAME={{ hostvars[inventory_hostname]['greenplum_hostname'] }}
#### File system location where the master data directory
#### will be created.
MASTER_DIRECTORY={{ greenplum_master_directory }}
#### Port number for the master instance.
MASTER_PORT={{ greenplum_master_port }}
#### Shell utility used to connect to remote hosts.
TRUSTED_SHELL=ssh
#### Maximum log file segments between automatic WAL checkpoints.
CHECK_POINT_SEGMENTS={{ greenplum_check_point_segments }}
#### Default server-side character set encoding.
ENCODING=UNICODE
################################################
#### OPTIONAL MIRROR PARAMETERS
################################################
#### Base number by which mirror segment port numbers
#### are calculated.
#MIRROR_PORT_BASE=7000
#### File system location(s) where mirror segment data directories
#### will be created. The number of mirror locations must equal the
#### number of primary locations as specified in the
#### DATA_DIRECTORY parameter.
#declare -a MIRROR_DATA_DIRECTORY=(/data1/mirror /data1/mirror /data1/mirror /data2/mirror /data2/mirror /data2/mirror)
################################################
#### OTHER OPTIONAL PARAMETERS
################################################
#### Create a database of this name after initialization.
#DATABASE_NAME=name_of_database
#### Specify the location of the host address file here instead of
#### with the -h option of gpinitsystem.
#MACHINE_LIST_FILE=/home/gpadmin/gpconfigs/hostfile_gpinitsystem

29
roles/greenplum-master/templates/greenplum.service.j2

@ -0,0 +1,29 @@
# {{ ansible_managed }}
[Unit]
Description=Greenplum database server
After=network.target
[Service]
Type=forking
User={{ greenplum_user }}
Group={{ greenplum_group }}
WorkingDirectory=/usr/local/greenplum-db/
# Disable OOM killer
OOMScoreAdjust=-1000
Environment=SHELL=/bin/bash
Environment="MASTER_DATA_DIRECTORY={{ greenplum_master_directory }}/{{ greenplum_seg_prefix }}-1"
ExecStart=/bin/bash -c "source {{ greenplum_user_profile_file }} && /usr/local/greenplum-db/bin/gpstart -a"
ExecStop=/bin/bash -c "source {{ greenplum_user_profile_file }} && /usr/local/greenplum-db/bin/gpstop -a"
ExecReload=/bin/bash -c "source {{ greenplum_user_profile_file }} && /usr/local/greenplum-db/bin/gpstop -a -r"
TimeoutSec=300
[Install]
WantedBy=multi-user.target

3
roles/greenplum-master/templates/hostfile_gpinitsystem.j2

@ -0,0 +1,3 @@
{% for host in groups['greenplum_segments'] %}
{{ hostvars[host]['greenplum_hostname'] }}
{% endfor %}

4
roles/greenplum-segment/defaults/main.yml

@ -0,0 +1,4 @@
---
greenplum_data_directory: /opt/data

14
roles/greenplum-segment/tasks/main.yml

@ -0,0 +1,14 @@
---
- name: greenplum segment | Make directory to store data
ansible.builtin.file:
path: "{{ greenplum_data_directory }}/{{ item }}"
owner: "{{ greenplum_user }}"
group: "{{ greenplum_group }}"
mode: 0644
state: directory
recurse: true
with_items:
- primary
- mirror

15
roles/greenplum/defaults/main.yml

@ -0,0 +1,15 @@
---
greenplum_src_directory: /opt/src
greenplum_version: 6.9.1
greenplum_db_rpm: "greenplum-db-{{ greenplum_version }}-rhel7-x86_64.rpm"
greenplum_contrib_repository: https://github.com/greenplum-db/gpdb
greenplum_contrib_version: 6X_STABLE
greenplum_contrib_exclude_list:
- btree_gin
- pgrowlocks

111
roles/greenplum/tasks/extensions-contrib.yml

@ -0,0 +1,111 @@
---
- name: contrib extensions | Install centos-release-scl
ansible.builtin.package:
name: centos-release-scl
state: present
- name: contrib extensions | Install build tools
ansible.builtin.package:
name:
- apr-devel
- bison
- bzip2-devel
- curl
- devtoolset-8
- flex
- git
- libcurl-devel
- libevent-devel
- libzstd-devel
- zlib-devel
state: present
- name: contrib extensions | Clone repository
become: true
become_user: "{{ greenplum_user }}"
ansible.builtin.git:
repo: "{{ greenplum_contrib_repository }}"
version: "{{ greenplum_contrib_version }}"
dest: "{{ greenplum_src_directory }}/contrib"
force: true
- name: contrib extensions | Disable excluded extensions
become: true
become_user: "{{ greenplum_user }}"
ansible.builtin.lineinfile:
dest: "{{ greenplum_src_directory }}/contrib/contrib/Makefile"
regexp: '\s+{{ item }}.*$'
state: absent
loop: "{{ greenplum_contrib_exclude_list }}"
- name: contrib extensions | Configure sources
become: true
become_user: "{{ greenplum_user }}"
ansible.builtin.shell: >
source {{ greenplum_user_profile_file }}
&& scl enable devtoolset-8 -- bash -c "./configure --prefix=$GPHOME --disable-gpcloud --without-readline"
args:
chdir: "{{ greenplum_src_directory }}/contrib"
tags: skip_ansible_lint
- name: contrib extensions | Build backend
become: true
become_user: "{{ greenplum_user }}"
ansible.builtin.shell: >
source {{ greenplum_user_profile_file }}
&& cd src/backend
&& scl enable devtoolset-8 -- make
args:
chdir: "{{ greenplum_src_directory }}/contrib"
tags: skip_ansible_lint
- name: contrib extensions | Build utils
become: true
become_user: "{{ greenplum_user }}"
ansible.builtin.shell: >
source {{ greenplum_user_profile_file }}
&& cd src/backend/utils
&& scl enable devtoolset-8 -- make
args:
chdir: "{{ greenplum_src_directory }}/contrib"
tags: skip_ansible_lint
- name: contrib extensions | Build extensions
become: true
become_user: "{{ greenplum_user }}"
ansible.builtin.shell: >
source {{ greenplum_user_profile_file }}
&& cd contrib
&& scl enable devtoolset-8 -- make
args:
chdir: "{{ greenplum_src_directory }}/contrib"
tags: skip_ansible_lint
- name: contrib extensions | Install extensions
ansible.builtin.shell: >
source {{ greenplum_user_profile_file }}
&& cd contrib/
&& make install
args:
chdir: "{{ greenplum_src_directory }}/contrib"
tags: skip_ansible_lint
- name: contrib extensions | Get list of available extensions
become: true
become_user: "{{ greenplum_user }}"
ansible.builtin.shell: |
source {{ greenplum_user_profile_file }}
psql postgres -t -c 'SELECT * FROM pg_available_extensions;' \
| cut -d '|' -f 1 \
| expand \
| sed 's/ \+$//' \
| tr '\n' ',' \
| sed 's/,\+$//'
register: contrib_extensions
tags: skip_ansible_lint
- name: contrib extensions | Show available extensions
ansible.builtin.debug:
msg: "The following extensions are available: {{ contrib_extensions.stdout }}"

67
roles/greenplum/tasks/main.yml

@ -0,0 +1,67 @@
---
- name: greenplum | Make directory to store package files
ansible.builtin.file:
path: "{{ greenplum_src_directory }}"
state: directory
owner: "{{ greenplum_user }}"
group: "{{ greenplum_group }}"
recurse: true
- name: greenplum | Upload Greenplum rpm package to the host
ansible.builtin.copy:
src: "{{ 'files/rpm/' ~ greenplum_db_rpm }}"
dest: "{{ greenplum_src_directory }}"
owner: "{{ greenplum_user }}"
group: "{{ greenplum_group }}"
mode: 0644
- name: greenplum | Install Greenplum server
ansible.builtin.yum:
name: "{{ greenplum_src_directory }}/{{ greenplum_db_rpm }}"
state: present
- name: greenplum | Find install directory
ansible.builtin.find:
paths: /usr/local
patterns: 'greenplum*'
file_type: directory
register: installed_dir
- name: greenplum | Change install directory ownership
ansible.builtin.file:
path: '{{ item.path }}'
owner: "{{ greenplum_user }}"
group: "{{ greenplum_group }}"
recurse: true
with_items: "{{ installed_dir.files }}"
- name: greenplum | Update pam_limits
community.general.pam_limits:
domain: "{{ greenplum_user }}"
limit_type: '-'
limit_item: "{{ item.key }}"
value: "{{ item.value }}"
with_dict:
nofile: 524288
nproc: 131072
- name: greenplum | Find installed Greenplum version
ansible.builtin.shell: . /usr/local/greenplum-db/greenplum_path.sh && /usr/local/greenplum-db/bin/postgres --gp-version
changed_when: false
register: postgres_gp_version
tags: skip_ansible_lint
- name: greenplum | Fail if the correct Greenplum version is not installed
ansible.builtin.fail:
msg: "Expected Greenplum version {{ greenplum_version }}, but found '{{ postgres_gp_version.stdout }}'"
when: "greenplum_version is not defined or greenplum_version not in postgres_gp_version.stdout"
- name: greenplum | Add Greenplum paths to {{ greenplum_user }} profile
ansible.builtin.lineinfile:
path: "{{ greenplum_user_profile_file }}"
line: "source /usr/local/greenplum-db/greenplum_path.sh"
# PostgreSQL database extensions
- include: 'extensions-contrib.yml'

8
roles/ntpd/defaults/main.yml

@ -0,0 +1,8 @@
---
ntp_pool_servers:
- 0.uk.pool.ntp.org
- 1.uk.pool.ntp.org
- 2.uk.pool.ntp.org
- 3.uk.pool.ntp.org

16
roles/ntpd/handlers/main.yml

@ -0,0 +1,16 @@
---
- name: start ntpd service
systemd:
name: ntpd
state: started
enabled: true
daemon_reload: yes
- name: restart ntpd service
systemd:
name: ntpd
state: restarted
enabled: true
daemon_reload: yes

17
roles/ntpd/tasks/main.yml

@ -0,0 +1,17 @@
---
- name: ntp | Install ntp package
package:
name: ntp
state: present
notify: start ntpd service
- name: ntp | Create ntp configuration file
template:
src: ntp.conf.j2
dest: "/etc/ntp.conf"
owner: root
group: root
mode: 0644
notify: restart ntpd service

60
roles/ntpd/templates/ntp.conf.j2

@ -0,0 +1,60 @@
# For more information about this file, see the man pages
# ntp.conf(5), ntp_acc(5), ntp_auth(5), ntp_clock(5), ntp_misc(5), ntp_mon(5).
driftfile /var/lib/ntp/drift
# Permit time synchronization with our time source, but do not
# permit the source to query or modify the service on this system.
restrict default nomodify notrap nopeer noquery
# Permit all access over the loopback interface. This could
# be tightened as well, but to do so would effect some of
# the administrative functions.
restrict 127.0.0.1
restrict ::1
# Hosts on local network are less restricted.
#restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
{% for pool in ntp_pool_servers %}
server {{ pool }} iburst
{% endfor %}
#broadcast 192.168.1.255 autokey # broadcast server
#broadcastclient # broadcast client
#broadcast 224.0.1.1 autokey # multicast server
#multicastclient 224.0.1.1 # multicast client
#manycastserver 239.255.254.254 # manycast server
#manycastclient 239.255.254.254 autokey # manycast client
# Enable public key cryptography.
#crypto
includefile /etc/ntp/crypto/pw
# Key file containing the keys and key identifiers used when operating
# with symmetric key cryptography.
keys /etc/ntp/keys
# Specify the key identifiers which are trusted.
#trustedkey 4 8 42
# Specify the key identifier to use with the ntpdc utility.
#requestkey 8
# Specify the key identifier to use with the ntpq utility.
#controlkey 8
# Enable writing of statistics records.
#statistics clockstats cryptostats loopstats peerstats
# Disable the monitoring facility to prevent amplification attacks using ntpdc
# monlist command when default restrict does not include the noquery flag. See
# CVE-2013-5211 for more details.
# Note: Monitoring will not be disabled with the limited restriction flag.
disable monitor
logfile /var/log/ntp.log

19
roles/prometheus-exporter/defaults/main.yml

@ -0,0 +1,19 @@
---
postgres_exporter_archive_url: https://github.com/wrouesnel/postgres_exporter/releases/download/v0.8.0/postgres_exporter_v0.8.0_linux-amd64.tar.gz
# enable | disable
postgres_exporter_sslmode: disable
# postgres_exporter_enabled: true
# postgres_exporter_user: user
# postgres_exporter_password: password
postgres_exporter_host: "127.0.0.1:5432"
postgres_exporter_database: "postgres"
postgres_exporter_listen_address: "0.0.0.0:9020"
postgres_exporter_telemetry_path: "/metrics"
# true | false
postgres_exporter_discovery: true

16
roles/prometheus-exporter/handlers/main.yml

@ -0,0 +1,16 @@
---
- name: start postgres_exporter service
ansible.builtin.systemd:
name: postgres_exporter
state: started
enabled: true
daemon_reload: true
- name: restart postgres_exporter service
ansible.builtin.systemd:
name: postgres_exporter
state: restarted
enabled: true
daemon_reload: true

27
roles/prometheus-exporter/tasks/main.yml

@ -0,0 +1,27 @@
---
- name: prometheus exporter | Download postgres_exporter release
ansible.builtin.unarchive:
src: "{{ postgres_exporter_archive_url }}"
dest: /usr/local/bin/
remote_src: true
extra_opts:
- --strip-components=1
notify: restart postgres_exporter service
- name: prometheus exporter | Create systemd service
ansible.builtin.template:
src: postgres_exporter.service.j2
dest: /etc/systemd/system/postgres_exporter.service
owner: root
group: root
mode: 0755
notify: restart postgres_exporter service
- name: prometheus exporter | Start exporter service
ansible.builtin.systemd:
name: postgres_exporter
state: started
enabled: true
daemon_reload: true

27
roles/prometheus-exporter/templates/postgres_exporter.service.j2

@ -0,0 +1,27 @@
# {{ ansible_managed }}
[Unit]
Description=Postgres metrics exporter
After=network.target
[Service]
Type=simple
User={{ greenplum_user }}
Group={{ greenplum_group }}
Environment="DATA_SOURCE_URI={{ postgres_exporter_host }}/{{ postgres_exporter_database }}?sslmode={{ postgres_exporter_sslmode }}"
Environment="DATA_SOURCE_USER={{ postgres_exporter_user }}"
Environment="DATA_SOURCE_PASS={{ postgres_exporter_password }}"
Environment="PG_EXPORTER_WEB_LISTEN_ADDRESS={{ postgres_exporter_listen_address }}"
Environment="PG_EXPORTER_WEB_TELEMETRY_PATH={{ postgres_exporter_telemetry_path }}"
Environment="PG_EXPORTER_AUTO_DISCOVER_DATABASES={{ postgres_exporter_discovery }}"
ExecStart=/usr/local/bin/postgres_exporter
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target

46
site.yml

@ -0,0 +1,46 @@
---
- hosts: all
pre_tasks:
- name: Check if python is available
raw: command -v python
changed_when: false
ignore_errors: true
register: python_exists
tags: skip_ansible_lint
- name: Install python using apt
raw: apt update && apt install -y python
tags: skip_ansible_lint
when:
- python_exists.rc != 0
- ansible_os_family == "Debian"
- name: Install python using yum
raw: yum install -y python
tags: skip_ansible_lint
when:
- python_exists.rc != 0
- ansible_os_family == "RedHat"
- hosts: greenplum_cluster
tasks:
- name: Disable SELinux
selinux:
state: disabled
roles:
- common
- ntpd
- greenplum
- hosts: greenplum_segments
roles:
- greenplum-segment
- hosts: greenplum_master
roles:
- role: greenplum-master
- role: prometheus-exporter
when: postgres_exporter_enabled
Loading…
Cancel
Save