Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rule revocation capabilities to ec2_group #23619

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
103 changes: 103 additions & 0 deletions lib/ansible/modules/cloud/amazon/ec2_group.py
Expand Up @@ -53,6 +53,20 @@
a default all-out rule is assumed. If an empty list is supplied, no outbound rules will be enabled.
required: false
version_added: "1.6"
revoke_rules:
version_added: "2.4"
description:
- List of firewall inbound rules to revoke in this group (see examples). If none are supplied,
nothing will change.
required: false
default: []
revoke_rules_egress:
version_added: "2.4"
description:
- List of firewall outbound rules to revoke in this group (see examples). If none are supplied,
nothing will change.
required: false
default: []
state:
version_added: "1.4"
description:
Expand Down Expand Up @@ -169,6 +183,21 @@
- 172.16.17.0/24
group_id:
- sg-edcd9784

# the example group will no longer accept connections on port 80
- name: example ec2 group revocation
ec2_group:
name: example
description: an example EC2 group
vpc_id: 12345
region: eu-west-1a
aws_secret_key: SECRET
aws_access_key: ACCESS
revoke_rules:
- proto: tcp
from_port: 80
to_port: 80
cidr_ip: 0.0.0.0/0
'''

import re
Expand Down Expand Up @@ -366,6 +395,8 @@ def main():
rules=dict(type='list'),
rules_egress=dict(type='list'),
state=dict(default='present', type='str', choices=['present', 'absent']),
revoke_rules=dict(default=[], required=False, type='list'),
revoke_rules_egress=dict(default=[], required=False, type='list'),
purge_rules=dict(default=True, required=False, type='bool'),
purge_rules_egress=dict(default=True, required=False, type='bool'),

Expand All @@ -385,6 +416,8 @@ def main():
rules = rules_expand_sources(rules_expand_ports(module.params['rules']))
rules_egress = rules_expand_sources(rules_expand_ports(module.params['rules_egress']))
state = module.params.get('state')
revoke_rules = rules_expand_sources(rules_expand_ports(module.params['revoke_rules']))
revoke_rules_egress = rules_expand_sources(rules_expand_ports(module.params['revoke_rules_egress']))
purge_rules = module.params['purge_rules']
purge_rules_egress = module.params['purge_rules_egress']

Expand Down Expand Up @@ -498,6 +531,38 @@ def main():
group.authorize(rule['proto'], rule['from_port'], rule['to_port'], thisip, grantGroup)
changed = True

# Revoke ingress rules
if revoke_rules is not None:
for rule in revoke_rules:
validate_rule(module, rule)

group_id, ip, target_group_created = get_target_from_rule(module, ec2, rule, name, group, groups, vpc_id)
if target_group_created:
changed = True

if rule['proto'] in ('all', '-1', -1):
rule['proto'] = -1
rule['from_port'] = None
rule['to_port'] = None

# Convert ip to list we can iterate over
if not isinstance(ip, list):
ip = [ip]

# Only try to revoke rule if it exists
for thisip in ip:
ruleId = make_rule_key('in', rule, group_id, thisip)
if ruleId in groupRules:
del groupRules[ruleId]

grantGroup = None
if group_id:
grantGroup = groups[group_id]

if not module.check_mode:
group.revoke(rule['proto'], rule['from_port'], rule['to_port'], thisip, grantGroup)
changed = True

# Finally, remove anything left in the groupRules -- these will be defunct rules
if purge_rules:
for (rule, grant) in groupRules.values():
Expand Down Expand Up @@ -575,6 +640,44 @@ def main():
# make sure the default egress rule is not removed
del groupRules[default_egress_rule]

# Revoke egress rules
if revoke_rules_egress is not None:
for rule in revoke_rules_egress:
validate_rule(module, rule)

group_id, ip, target_group_created = get_target_from_rule(module, ec2, rule, name, group, groups, vpc_id)
if target_group_created:
changed = True

if rule['proto'] in ('all', '-1', -1):
rule['proto'] = -1
rule['from_port'] = None
rule['to_port'] = None

# Convert ip to list we can iterate over
if not isinstance(ip, list):
ip = [ip]

# Only try to revoke rule if it exists
for thisip in ip:
ruleId = make_rule_key('in', rule, group_id, thisip)
if ruleId in groupRules:
del groupRules[ruleId]

grantGroup = None
if group_id:
grantGroup = groups[group_id].id

if not module.check_mode:
ec2.revoke_security_group_egress(
group_id=group.id,
ip_protocol=rule['proto'],
from_port=rule['from_port'],
to_port=rule['to_port'],
src_group_id=grantGroup,
cidr_ip=thisip)
changed = True

# Finally, remove anything left in the groupRules -- these will be defunct rules
if purge_rules_egress:
for (rule, grant) in groupRules.values():
Expand Down