Improve ecs_ecr module to handle image_tag_mutability feature (#62871)
Since 2019 jul. 26, AWS Elastic Container Registry can be configured to be immutable that prevent overwritting of an existing tag in the registry. https://aws.amazon.com/fr/about-aws/whats-new/2019/07/amazon-ecr-now-supports-immutable-image-tags/ https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-tag-mutability.html By default, ecr is created MUTABLE, as this was the only option before this feature. This module leverage new capabilities of boto3 to configure image_tag_mutability option. https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ecr.html#ECR.Client.put_image_tag_mutability The image_tag_mutability option definition was inspired by existing terraform module. https://www.terraform.io/docs/providers/aws/r/ecr_repository.html
This commit is contained in:
parent
df283788e5
commit
29939383e6
2 changed files with 121 additions and 8 deletions
|
@ -5,14 +5,13 @@
|
|||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ecs_ecr
|
||||
|
@ -48,6 +47,13 @@ options:
|
|||
required: false
|
||||
default: false
|
||||
type: bool
|
||||
image_tag_mutability:
|
||||
description:
|
||||
- configure whether repository should be mutable (ie. an already existing tag can be overwritten) or not
|
||||
required: false
|
||||
choices: [mutable, immutable]
|
||||
default: 'mutable'
|
||||
version_added: '2.10'
|
||||
state:
|
||||
description:
|
||||
- create or destroy the repository
|
||||
|
@ -97,6 +103,12 @@ EXAMPLES = '''
|
|||
ecs_ecr:
|
||||
name: needs-no-policy
|
||||
delete_policy: yes
|
||||
|
||||
- name: create immutable ecr-repo
|
||||
ecs_ecr:
|
||||
name: super/cool
|
||||
image_tag_mutability: immutable
|
||||
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
|
@ -190,15 +202,17 @@ class EcsEcr:
|
|||
return None
|
||||
raise
|
||||
|
||||
def create_repository(self, registry_id, name):
|
||||
def create_repository(self, registry_id, name, image_tag_mutability):
|
||||
if registry_id:
|
||||
default_registry_id = self.sts.get_caller_identity().get('Account')
|
||||
if registry_id != default_registry_id:
|
||||
raise Exception('Cannot create repository in registry {0}.'
|
||||
'Would be created in {1} instead.'.format(
|
||||
registry_id, default_registry_id))
|
||||
'Would be created in {1} instead.'.format(registry_id, default_registry_id))
|
||||
|
||||
if not self.check_mode:
|
||||
repo = self.ecr.create_repository(repositoryName=name).get('repository')
|
||||
repo = self.ecr.create_repository(
|
||||
repositoryName=name,
|
||||
imageTagMutability=image_tag_mutability).get('repository')
|
||||
self.changed = True
|
||||
return repo
|
||||
else:
|
||||
|
@ -250,6 +264,23 @@ class EcsEcr:
|
|||
return policy
|
||||
return None
|
||||
|
||||
def put_image_tag_mutability(self, registry_id, name, new_mutability_configuration):
|
||||
repo = self.get_repository(registry_id, name)
|
||||
current_mutability_configuration = repo.get('imageTagMutability')
|
||||
|
||||
if current_mutability_configuration != new_mutability_configuration:
|
||||
if not self.check_mode:
|
||||
self.ecr.put_image_tag_mutability(
|
||||
repositoryName=name,
|
||||
imageTagMutability=new_mutability_configuration,
|
||||
**build_kwargs(registry_id))
|
||||
else:
|
||||
self.skipped = True
|
||||
self.changed = True
|
||||
|
||||
repo['imageTagMutability'] = new_mutability_configuration
|
||||
return repo
|
||||
|
||||
|
||||
def sort_lists_of_strings(policy):
|
||||
for statement_index in range(0, len(policy.get('Statement', []))):
|
||||
|
@ -270,6 +301,7 @@ def run(ecr, params, verbosity):
|
|||
delete_policy = params['delete_policy']
|
||||
registry_id = params['registry_id']
|
||||
force_set_policy = params['force_set_policy']
|
||||
image_tag_mutability = params['image_tag_mutability'].upper()
|
||||
|
||||
# If a policy was given, parse it
|
||||
policy = policy_text and json.loads(policy_text)
|
||||
|
@ -281,10 +313,13 @@ def run(ecr, params, verbosity):
|
|||
|
||||
if state == 'present':
|
||||
result['created'] = False
|
||||
|
||||
if not repo:
|
||||
repo = ecr.create_repository(registry_id, name)
|
||||
repo = ecr.create_repository(registry_id, name, image_tag_mutability)
|
||||
result['changed'] = True
|
||||
result['created'] = True
|
||||
else:
|
||||
repo = ecr.put_image_tag_mutability(registry_id, name, image_tag_mutability)
|
||||
result['repository'] = repo
|
||||
|
||||
if delete_policy:
|
||||
|
@ -358,7 +393,9 @@ def main():
|
|||
default='present'),
|
||||
force_set_policy=dict(required=False, type='bool', default=False),
|
||||
policy=dict(required=False, type='json'),
|
||||
delete_policy=dict(required=False, type='bool')))
|
||||
delete_policy=dict(required=False, type='bool'),
|
||||
image_tag_mutability=dict(required=False, choices=['mutable', 'immutable'],
|
||||
default='mutable')))
|
||||
|
||||
module = AnsibleModule(argument_spec=argument_spec,
|
||||
supports_check_mode=True,
|
||||
|
|
|
@ -55,6 +55,11 @@
|
|||
- result is changed
|
||||
- result.created
|
||||
|
||||
- name: it should have been configured as mutable by default
|
||||
assert:
|
||||
that:
|
||||
- result.repository.imageTagMutability == "MUTABLE"
|
||||
|
||||
|
||||
- name: When creating a repository that already exists in check mode
|
||||
ecs_ecr:
|
||||
|
@ -329,6 +334,77 @@
|
|||
that:
|
||||
- result is not changed
|
||||
|
||||
- name: When creating an immutable repository
|
||||
ecs_ecr:
|
||||
name: '{{ ecr_name }}'
|
||||
region: '{{ ec2_region }}'
|
||||
ec2_access_key: '{{ec2_access_key}}'
|
||||
ec2_secret_key: '{{ec2_secret_key}}'
|
||||
security_token: '{{security_token}}'
|
||||
image_tag_mutability: immutable
|
||||
register: result
|
||||
|
||||
- name: it should change and create
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
- result.created
|
||||
|
||||
- name: it should have been configured as immutable
|
||||
assert:
|
||||
that:
|
||||
- result.repository.imageTagMutability == "IMMUTABLE"
|
||||
|
||||
|
||||
- name: When configuring an existing immutable repository to be mutable in check mode
|
||||
ecs_ecr:
|
||||
name: '{{ ecr_name }}'
|
||||
region: '{{ ec2_region }}'
|
||||
ec2_access_key: '{{ec2_access_key}}'
|
||||
ec2_secret_key: '{{ec2_secret_key}}'
|
||||
security_token: '{{security_token}}'
|
||||
image_tag_mutability: mutable
|
||||
register: result
|
||||
check_mode: yes
|
||||
|
||||
- name: it should skip, change and configured mutable
|
||||
assert:
|
||||
that:
|
||||
- result is skipped
|
||||
- result is changed
|
||||
- result.repository.imageTagMutability == "MUTABLE"
|
||||
|
||||
- name: When configuring an existing immutable repository to be mutable
|
||||
ecs_ecr:
|
||||
name: '{{ ecr_name }}'
|
||||
region: '{{ ec2_region }}'
|
||||
ec2_access_key: '{{ec2_access_key}}'
|
||||
ec2_secret_key: '{{ec2_secret_key}}'
|
||||
security_token: '{{security_token}}'
|
||||
image_tag_mutability: mutable
|
||||
register: result
|
||||
|
||||
- name: it should change and configured mutable
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
- result.repository.imageTagMutability == "MUTABLE"
|
||||
|
||||
- name: When configuring an already mutable repository to be mutable
|
||||
ecs_ecr:
|
||||
name: '{{ ecr_name }}'
|
||||
region: '{{ ec2_region }}'
|
||||
ec2_access_key: '{{ec2_access_key}}'
|
||||
ec2_secret_key: '{{ec2_secret_key}}'
|
||||
security_token: '{{security_token}}'
|
||||
image_tag_mutability: mutable
|
||||
register: result
|
||||
|
||||
- name: it should not change
|
||||
assert:
|
||||
that:
|
||||
- result is not changed
|
||||
|
||||
always:
|
||||
|
||||
- name: Delete lingering ECR repository
|
||||
|
|
Loading…
Reference in a new issue