diff --git a/roles/anope/defaults/main.yml b/roles/anope/defaults/main.yml
new file mode 100644
index 0000000..5728e30
--- /dev/null
+++ b/roles/anope/defaults/main.yml
@@ -0,0 +1,132 @@
+---
+
+anope_services_botserv_enabled: false
+anope_services_chanserv_enabled: true
+anope_services_global_enabled: true
+anope_services_hostserv_enabled: false
+anope_services_memoserv_enabled: false
+anope_services_nickserv_enabled: true
+anope_services_operserv_enabled: true
+
+anope_services_host: services.localhost.localdomain
+
+anope_uplink_host: localhost
+anope_uplink_ipv6: true
+anope_uplink_ssl: false
+anope_uplink_port: 7000
+
+anope_serverinfo_name: services.localhost.localdomain
+anope_serverinfo_description: Services for IRC Networks
+anope_serverinfo_pid: /var/run/anope/anope.pid
+anope_serverinfo_motd: /etc/anope/services.motd
+
+anope_protocol_module_name: inspircd3
+anope_protocol_module_use_server_side_mlock: true
+anope_protocol_module_use_server_side_topiclock: true
+
+anope_networkinfo_networkname: LocalNet
+anope_networkinfo_nicklen: 31
+anope_networkinfo_userlen: 10
+anope_networkinfo_hostlen: 64
+anope_networkinfo_chanlen: 32
+anope_networkinfo_modelistsize: 100
+anope_networkinfo_vhost_chars: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-"
+anope_networkinfo_allow_undotted_vhosts: false
+anope_networkinfo_disallow_start_or_end: ".-"
+
+anope_options_casemap: ascii
+anope_options_strictpasswords: true
+anope_options_badpasslimit: 5
+anope_options_badpasstimeout: 1h
+anope_options_updatetimeout: 5m
+anope_options_expiretimeout: 30m
+anope_options_readtimeout: 5s
+anope_options_warningtimeout: 4h
+anope_options_timeoutcheck: 3s
+anope_options_retrywait: 60s
+anope_options_hideprivilegedcommands: yes
+anope_options_hideregisteredcommands: yes
+anope_options_languages:
+  - ca_ES.UTF-8
+  - de_DE.UTF-8
+  - el_GR.UTF-8
+  - en_US.UTF-8
+  - es_ES.UTF-8
+  - fr_FR.UTF-8
+  - hu_HU.UTF-8
+  - it_IT.UTF-8
+  - nl_NL.UTF-8
+  - pl_PL.UTF-8
+  - pt_PT.UTF-8
+  - ru_RU.UTF-8
+  - tr_TR.UTF-8
+anope_options_defaultlanguage: en_US.UTF-8
+
+anope_log:
+  - targets:
+      - services.log
+    sources: []
+    bot: Global
+    logage: 7
+    admin:
+      - "*"
+    override:
+      - chanserv/*
+      - nickserv/*
+      - memoserv/set
+      - ~botserv/set
+      - botserv/*
+    commands:
+      - ~operserv/*
+      - "*"
+    servers:
+      - "*"
+    users:
+      - connect
+      - disconnect
+      - nick
+    other:
+      - "*"
+    rawio: no
+    debug: no
+  - targets:
+      - globops
+    admin:
+      - "global/*"
+      - "operserv/chankill"
+      - "operserv/mode"
+      - "operserv/kick"
+      - "operserv/akill"
+      - "operserv/s*line"
+      - "operserv/noop"
+      - "operserv/jupe"
+      - "operserv/oline"
+      - "operserv/set"
+      - "operserv/svsnick"
+      - "operserv/svsjoin"
+      - "operserv/svspart"
+      - "nickserv/getpass"
+      - "*/drop"
+    servers:
+      - squit
+    users:
+      - oper
+    other:
+      - "expire/*"
+      - "bados"
+      - "akill/*"
+    
+anope_opertypes:
+  NetAdmin:
+    commands: ["*"]
+    privs: ["*"]
+
+anope_opers: {}
+
+anope_database_flatfile_keepbackups: 3
+anope_database_flatfile_nobackupok: no
+anope_database_flatfile_fork: no
+
+anope_password_hash: bcrypt
+
+anope_additional_config: ""
diff --git a/roles/anope/handlers/main.yml b/roles/anope/handlers/main.yml
new file mode 100644
index 0000000..f1e6f70
--- /dev/null
+++ b/roles/anope/handlers/main.yml
@@ -0,0 +1,11 @@
+---
+
+- name: restart anope
+  service:
+    name: anope
+    state: restarted
+
+- name: reload anope
+  service:
+    name: anope
+    state: reloaded
diff --git a/roles/anope/tasks/config.yml b/roles/anope/tasks/config.yml
new file mode 100644
index 0000000..cf686dc
--- /dev/null
+++ b/roles/anope/tasks/config.yml
@@ -0,0 +1,25 @@
+---
+
+- name: render /etc/anope/services.conf
+  template:
+    src: etc/anope/services.conf.j2
+    dest: /etc/anope/services.conf
+    owner: root
+    group: irc
+    mode: 0640
+  notify: restart anope
+
+- name: render /etc/default/anope
+  template:
+    src: etc/default/anope.j2
+    dest: /etc/default/anope
+    owner: root
+    group: root
+    mode: 0644
+  notify: restart anope
+
+- name: start and enable anope
+  service:
+    name: anope
+    state: started
+    enabled: yes
diff --git a/roles/anope/tasks/install.yml b/roles/anope/tasks/install.yml
new file mode 100644
index 0000000..a69f632
--- /dev/null
+++ b/roles/anope/tasks/install.yml
@@ -0,0 +1,7 @@
+---
+
+- name: install anope
+  apt:
+    name: anope
+    # anope recommends default-mta, which resolves to exim
+    install_recommends : no
diff --git a/roles/anope/tasks/main.yml b/roles/anope/tasks/main.yml
new file mode 100644
index 0000000..542cbf0
--- /dev/null
+++ b/roles/anope/tasks/main.yml
@@ -0,0 +1,11 @@
+---
+
+- import_tasks: install.yml
+  tags:
+    - "role::anope"
+    - "role::anope:install"
+
+- import_tasks: config.yml
+  tags:
+    - "role::anope"
+    - "role::anope:config"
diff --git a/roles/anope/templates/etc/anope/services.conf.j2 b/roles/anope/templates/etc/anope/services.conf.j2
new file mode 100644
index 0000000..ab569de
--- /dev/null
+++ b/roles/anope/templates/etc/anope/services.conf.j2
@@ -0,0 +1,191 @@
+{{ ansible_managed | comment }}
+
+define
+{
+	name = "services.host"
+	value = "{{ anope_services_host }}"
+}
+
+uplink
+{
+	host = "{{ anope_uplink_host }}"
+	ipv6 = {{ anope_uplink_ipv6 | ternary('yes', 'no') }}
+	ssl = {{ anope_uplink_ssl | ternary('yes', 'no') }}
+	port = {{ anope_uplink_port }}
+	password = "{{ anope_uplink_password }}"
+}
+
+serverinfo
+{
+	name = "{{ anope_serverinfo_name }}"
+	description = "{{ anope_serverinfo_description }}"
+	{% if anope_serverinfo_localhost is defined %}localhost = "{{ anope_serverinfo_localhost }}"{% endif %}
+	{% if anope_serverinfo_id is defined %}id = "{{ anope_serverinfo_id }}"{% endif %}
+	pid = "{{ anope_serverinfo_pid }}"
+	motd = "{{ anope_serverinfo_motd }}"
+}
+
+module
+{
+	name = "{{ anope_protocol_module_name }}"
+	use_server_side_mlock = {{ anope_protocol_module_use_server_side_mlock | ternary('yes', 'no') }}
+	use_server_side_topiclock = {{ anope_protocol_module_use_server_side_topiclock | ternary('yes', 'no') }}
+}
+
+networkinfo
+{
+	networkname = "{{ anope_networkinfo_networkname }}"
+	nicklen = {{ anope_networkinfo_nicklen }}
+	userlen = {{ anope_networkinfo_userlen }}
+	hostlen = {{ anope_networkinfo_hostlen }}
+	chanlen = {{ anope_networkinfo_chanlen }}
+	modelistsize = {{ anope_networkinfo_modelistsize }}
+	{% if anope_networkinfo_nick_chars is defined %}nick_chars = "{{ anope_networkinfo_nick_chars }}"{% endif %}
+	vhost_chars = "{{ anope_networkinfo_vhost_chars }}"
+	allow_undotted_vhosts = {{ anope_networkinfo_allow_undotted_vhosts | ternary('yes', 'no') }}
+	disallow_start_or_end = "{{ anope_networkinfo_disallow_start_or_end }}"
+}
+
+options
+{
+	{% if anope_options_user is defined %}user = "{{ anope_options_user }}"{% endif %}
+	{% if anope_options_group is defined %}group = "{{ anope_options_group }}"{% endif %}
+	casemap = "{{ anope_options_casemap }}"
+	seed = {{ anope_options_seed }}
+	strictpasswords = {{ anope_options_strictpasswords | ternary('yes', 'no' ) }}
+	badpasslimit = {{ anope_options_badpasslimit }}
+	badpasstimeout = {{ anope_options_badpasstimeout }}
+	updatetimeout = {{ anope_options_updatetimeout }}
+	expiretimeout = {{ anope_options_expiretimeout }}
+	readtimeout = {{ anope_options_readtimeout }}
+	warningtimeout = {{ anope_options_warningtimeout }}
+	timeoutcheck = {{ anope_options_timeoutcheck }}
+	{% if anope_options_useprivmsg is defined %}useprivmsg = {{ anope_options_useprivmsg | ternary('yes', 'no') }}{% endif %}
+	{% if anope_options_usestrictprivmsg is defined %}usestrictprivmsg = {{ anope_options_usestrictprivmsg | ternary('yes', 'no') }}{% endif %}
+	{% if anope_options_hidestatso is defined %}hidestatso = {{ anope_options_hidestatso | ternary('yes', 'no') }}{% endif %}
+	{% if anope_options_ulineservers is defined %}ulineservers = "{{ anope_options_ulineservers | join(' ') }}"{% endif %}
+	retrywait = {{ anope_options_retrywait }}
+	hideprivilegedcommands = {{ anope_options_hideprivilegedcommands | ternary('yes', 'no') }}
+	hideregisteredcommands = {{ anope_options_hideregisteredcommands | ternary('yes', 'no') }}
+	{% if anope_options_regexengine is defined %}regexengine = "regex/pcre"{% endif %}
+	languages = "{{ anope_options_languages | join(' ') }}"
+	anope_options_defaultlanguage = "{{ anope_options_defaultlanguage }}"
+}
+
+{% for log in anope_log %}
+log
+{
+	target = "{{ log.targets | join(' ') }}"
+	{% if 'source' in log %}source = "{{ log.source }}"{% endif %}
+	{% if 'bot' in log %}bot = "{{ log.bot }}"{% endif %}
+	{% if 'logage' in log %}logage = {{ log.logage }}{% endif %}
+	{% if 'admin' in log %}admin = "{{ log.admin | join(' ') }}"{% endif %}
+	{% if 'override' in log %}override = "{{ log.override | join(' ') }}"{% endif %}
+	{% if 'commands' in log %}commands = "{{ log.commands | join(' ') }}"{% endif %}
+	{% if 'servers' in log %}servers = "{{ log.servers | join(' ') }}"{% endif %}
+	{% if 'channels' in log %}channels = "{{ log.channels | join(' ') }}"{% endif %}
+	{% if 'users' in log %}users = "{{ log.users | join(' ') }}"{% endif %}
+	{% if 'other' in log %}other = "{{ log.other | join(' ') }}"{% endif %}
+	{% if 'rawio' in log %}rawio = {{ log.rawio | ternary('yes', 'no') }}{% endif %}
+	{% if 'debug' in log %}debug = {{ log.debug | ternary('yes', 'no') }}{% endif %}
+}
+
+{% endfor %}
+
+{% for name, opertype in anope_opertypes.items() %}
+opertype
+{
+	name = "{{ name }}"
+	commands = "{{ log.commands | join(' ') }}"
+	privs = "{{ log.privs | join(' ') }}"
+	{% if 'inherits' in opertype %}inherits = "{{ log.inherits | join(', ') }}"{% endif %}
+	{% if 'modes' in opertype %}modes = "{{ log.modes }}"{% endif %}
+}
+{% endfor %}
+
+{% for name, op in anope_opers.items() %}
+oper
+{
+	name = "{{ name }}"
+	type = "{{ op.type }}"
+	{% if 'require_oper' in op%}require_oper = {{ op.require_oper | ternary('yes', 'no') }}{% endif %}
+	{% if 'password' in op%}password = "{{ op.password }}"{% endif %}
+	{% if 'certfp' in op%}certfp = "{{ op.certfp }}"{% endif %}
+	{% if 'host' in op%}host = "{{ op.host }}"{% endif %}
+	{% if 'vhost' in op%}vhost = "{{ op.vhost }}"{% endif %}
+}
+{% endfor %}
+
+module
+{
+	name = "db_flatfile"
+	database = "{{ anope_database_flatfile_filename }}"
+	keepbackups = {{ anope_database_flatfile_keepbackups }}
+	nobackupok = {{ anope_database_flatfile_nobackupok | ternary('yes', 'no') }}
+	fork = {{ anope_database_flatfile_fork | ternary('yes', 'no') }}
+}
+
+module
+{
+	name = "enc_{{ anope_password_hash }}"
+}
+
+{% if anope_services_botserv_enabled %}
+include
+{
+        type = "file"
+        name = "botserv.conf"
+}
+{% endif %}
+
+{% if anope_services_chanserv_enabled %}
+include
+{
+        type = "file"
+        name = "chanserv.conf"
+}
+{% endif %}
+
+{% if anope_services_global_enabled %}
+include
+{
+        type = "file"
+        name = "global.conf"
+}
+{% endif %}
+
+{% if anope_services_hostserv_enabled %}
+include
+{
+        type = "file"
+        name = "hostserv.conf"
+}
+{% endif %}
+
+{% if anope_services_memoserv_enabled %}
+include
+{
+        type = "file"
+        name = "memoserv.conf"
+}
+{% endif %}
+
+{% if anope_services_nickserv_enabled %}
+include
+{
+        type = "file"
+        name = "nickserv.conf"
+}
+{% endif %}
+
+{% if anope_services_operserv_enabled %}
+include
+{
+        type = "file"
+        name = "operserv.conf"
+}
+{% endif %}
+
+
+
+{{ anope_additional_config }}
\ No newline at end of file
diff --git a/roles/anope/templates/etc/default/anope.j2 b/roles/anope/templates/etc/default/anope.j2
new file mode 100644
index 0000000..057bb6b
--- /dev/null
+++ b/roles/anope/templates/etc/default/anope.j2
@@ -0,0 +1,2 @@
+{{ ansible_managed | comment }}
+START=yes