diff --git a/roles/koji-web/defaults/main.yml b/roles/koji-web/defaults/main.yml
new file mode 100644
index 0000000..32c73ac
--- /dev/null
+++ b/roles/koji-web/defaults/main.yml
@@ -0,0 +1,11 @@
+koji_uid: 998
+koji_gid: 996
+koji_home: /var/lib/koji
+kojihub_host: "{{ ansible_fqdn }}"
+kojihub_url: https://{{ kojihub_host }}/kojihub
+kojiweb_hostname: "{{ kojihub_host }}"
+kojiweb_url: https://{{ kojiweb_hostname }}/koji
+kojifiles_host: "{{ kojihub_host }}"
+kojifiles_url: http://{{ kojifiles_host }}/kojifiles
+kojiweb_secret: >
+ {{ lookup("password", "passwords/kojiweb_secret/" + inventory_hostname) }}
diff --git a/roles/koji-web/handlers/main.yml b/roles/koji-web/handlers/main.yml
new file mode 100644
index 0000000..b898998
--- /dev/null
+++ b/roles/koji-web/handlers/main.yml
@@ -0,0 +1,2 @@
+- name: update ca trust
+ command: update-ca-trust
diff --git a/roles/koji-web/tasks/main.yml b/roles/koji-web/tasks/main.yml
new file mode 100644
index 0000000..9569f6c
--- /dev/null
+++ b/roles/koji-web/tasks/main.yml
@@ -0,0 +1,64 @@
+- name: ensure packages are installed
+ package:
+ name={{ koji_web_packages|join(',') }}
+ state=present
+ tags:
+ - install
+ notify: restart httpd
+- meta: flush_handlers
+
+- name: ensure koji group exists
+ group:
+ name=koji
+ gid={{ koji_gid }}
+ state=present
+- name: ensure koji user exists
+ user:
+ name=koji
+ home={{ koji_home }}
+ createhome=no
+ group=koji
+ uid={{ koji_uid }}
+ state=present
+
+- name: ensure koji web certificate is installed
+ copy:
+ src={{ item }}
+ dest=/etc/kojiweb/{{ item|basename }}
+ mode=0440
+ owner=root
+ group=koji
+ with_fileglob:
+ - certs/koji/{{ inventory_hostname }}/kojiweb.pem
+- name: ensure koji web ca certificates are installed
+ copy:
+ src={{ item }}
+ dest=/etc/kojiweb/{{ item|basename }}
+ mode=0644
+ with_fileglob:
+ - certs/koji/{{ inventory_hostname }}/*.crt
+- name: ensure koji hub server ca certificate is trusted
+ copy:
+ src={{ item }}
+ dest=/etc/pki/ca-trust/source/anchors/koji-hub.crt
+ mode=0644
+ with_fileglob:
+ - certs/koji/{{ inventory_hostname }}/kojihubca.crt
+ notify: update ca trust
+- name: ensure koji web is configured
+ template:
+ src=web.conf.j2
+ dest=/etc/kojiweb/web.conf
+ mode=0644
+ notify: reload httpd
+
+- name: ensure apache is configured to serve koji web
+ template:
+ src=kojiweb.httpd.conf.j2
+ dest=/etc/httpd/conf.d/kojiweb.conf
+ notify: reload httpd
+- name: ensure apache is allowed to make network connections
+ seboolean:
+ name=httpd_can_network_connect
+ persistent=yes
+ state=yes
diff --git a/roles/koji-web/templates/kojiweb.httpd.conf.j2 b/roles/koji-web/templates/kojiweb.httpd.conf.j2
new file mode 100644
index 0000000..d9ca360
--- /dev/null
+++ b/roles/koji-web/templates/kojiweb.httpd.conf.j2
@@ -0,0 +1,72 @@
+
+ Include conf.d/ssl.include
+
+ SSLCertificateFile {{ apache_ssl_certificate }}
+ SSLCertificateKeyFile {{ apache_ssl_certificate_key }}
+ SSLCertificateChainFile {{ apache_ssl_certificate }}
+ SSLCACertificateFile {{ apache_ssl_ca_certificate }}
+
+ RewriteEngine On
+ RewriteRule ^/?$ /koji/ [R=301,L]
+
+
+RewriteEngine On
+RewriteCond %{HTTPS} !on
+RewriteRule /koji/.* https://{{ kojiweb_hostname }}$0 [R=301,L]
+
+#We use wsgi by default
+#Alias /koji "/usr/share/koji-web/scripts/wsgi_publisher.py"
+#(configuration goes in /etc/kojiweb/web.conf)
+
+WSGIDaemonProcess kojiweb \
+ user=koji \
+ group=koji \
+ display-name=%{GROUP}
+WSGIScriptAlias /koji /usr/share/koji-web/scripts/wsgi_publisher.py \
+ process-group=koji
+
+
+
+ Order allow,deny
+ Allow from all
+
+ = 2.4>
+ Require all granted
+
+
+
+# uncomment this to enable authentication via Kerberos
+#
+# AuthType Kerberos
+# AuthName "Koji Web UI"
+# KrbMethodNegotiate on
+# KrbMethodK5Passwd off
+# KrbServiceName HTTP
+# KrbAuthRealm EXAMPLE.COM
+# Krb5Keytab /etc/httpd.keytab
+# KrbSaveCredentials off
+# Require valid-user
+# ErrorDocument 401 /koji-static/errors/unauthorized.html
+#
+
+# uncomment this to enable authentication via SSL client certificates
+
+ SSLVerifyClient optional
+ SSLVerifyDepth 10
+ SSLOptions +StdEnvVars
+ ErrorDocument 401 /koji-static/errors/unauthorized.html
+
+
+Alias /koji-static/ "/usr/share/koji-web/static/"
+
+
+ Options None
+ AllowOverride None
+
+ Order allow,deny
+ Allow from all
+
+ = 2.4>
+ Require all granted
+
+
diff --git a/roles/koji-web/templates/web.conf.j2 b/roles/koji-web/templates/web.conf.j2
new file mode 100644
index 0000000..240a2a4
--- /dev/null
+++ b/roles/koji-web/templates/web.conf.j2
@@ -0,0 +1,37 @@
+{#- vim: set ft=jinja : -#}
+[web]
+SiteName = koji
+#KojiTheme = mytheme
+
+# Key urls
+KojiHubURL = {{ kojihub_url }}
+KojiFilesURL = {{ kojifiles_url }}
+
+# Kerberos authentication options
+# WebPrincipal = koji/web@EXAMPLE.COM
+# WebKeytab = /etc/httpd.keytab
+# WebCCache = /var/tmp/kojiweb.ccache
+# The service name of the principal being used by the hub
+# KrbService = host
+
+# SSL authentication options
+WebCert = /etc/kojiweb/kojiweb.pem
+ClientCA = /etc/kojiweb/clientca.crt
+KojiHubCA = /etc/kojiweb/kojihubca.crt
+
+LoginTimeout = 72
+
+# This must be changed and uncommented before deployment
+Secret = {{ kojiweb_secret }}
+
+LibPath = /usr/share/koji-web/lib
+
+# If set to True, then the footer will be included literally.
+# If False, then the footer will be included as another Kid Template.
+# Defaults to True
+LiteralFooter = True
+
+# This can be a space-delimited list of the numeric IDs of users that you want
+# to hide from tasks listed on the front page. You might want to, for instance,
+# hide the activity of an account used for continuous integration.
+#HiddenUsers = 5372 1234
diff --git a/roles/koji-web/vars/main.yml b/roles/koji-web/vars/main.yml
new file mode 100644
index 0000000..61431fe
--- /dev/null
+++ b/roles/koji-web/vars/main.yml
@@ -0,0 +1,2 @@
+koji_web_packages:
+- koji-web