From 3838eac44a96a358678530da17d7d99b5fa50823 Mon Sep 17 00:00:00 2001 From: Helen Bailey Date: Fri, 12 May 2023 13:44:32 -0400 Subject: [PATCH 01/11] Add integration test config file to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f96f3079..b6b7bb4f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /tests/output/ +/tests/integration/integration_config.yml /tests/integration/inventory /changelogs/.plugin-cache.yaml tests/integration/cloud-config-* From 8e57b07514685db075b7b71eaceb75eae24e480b Mon Sep 17 00:00:00 2001 From: Helen Bailey Date: Tue, 6 Jun 2023 10:30:52 -0400 Subject: [PATCH 02/11] Add backup create_plan and select_resources roles --- roles/backup_create_plan/README.md | 58 ++++++++ roles/backup_create_plan/defaults/main.yaml | 7 + roles/backup_create_plan/meta/main.yaml | 3 + roles/backup_create_plan/tasks/main.yaml | 54 ++++++++ roles/backup_create_plan/vars/main.yaml | 30 +++++ roles/backup_select_resources/README.md | 52 ++++++++ .../defaults/main.yaml | 6 + roles/backup_select_resources/meta/main.yaml | 3 + roles/backup_select_resources/tasks/main.yaml | 60 +++++++++ roles/backup_select_resources/vars/main.yaml | 19 +++ .../test_backup_create_plan/defaults/main.yml | 2 + .../test_backup_create_plan/tasks/main.yml | 125 ++++++++++++++++++ .../defaults/main.yml | 6 + .../files/backup-policy.json | 12 ++ .../tasks/main.yml | 106 +++++++++++++++ .../tasks/setup.yml | 24 ++++ .../tasks/teardown.yml | 34 +++++ 17 files changed, 601 insertions(+) create mode 100644 roles/backup_create_plan/README.md create mode 100644 roles/backup_create_plan/defaults/main.yaml create mode 100644 roles/backup_create_plan/meta/main.yaml create mode 100644 roles/backup_create_plan/tasks/main.yaml create mode 100644 roles/backup_create_plan/vars/main.yaml create mode 100644 roles/backup_select_resources/README.md create mode 100644 roles/backup_select_resources/defaults/main.yaml create mode 100644 roles/backup_select_resources/meta/main.yaml create mode 100644 roles/backup_select_resources/tasks/main.yaml create mode 100644 roles/backup_select_resources/vars/main.yaml create mode 100644 tests/integration/targets/test_backup_create_plan/defaults/main.yml create mode 100644 tests/integration/targets/test_backup_create_plan/tasks/main.yml create mode 100644 tests/integration/targets/test_backup_select_resources/defaults/main.yml create mode 100644 tests/integration/targets/test_backup_select_resources/files/backup-policy.json create mode 100644 tests/integration/targets/test_backup_select_resources/tasks/main.yml create mode 100644 tests/integration/targets/test_backup_select_resources/tasks/setup.yml create mode 100644 tests/integration/targets/test_backup_select_resources/tasks/teardown.yml diff --git a/roles/backup_create_plan/README.md b/roles/backup_create_plan/README.md new file mode 100644 index 00000000..9c2098b3 --- /dev/null +++ b/roles/backup_create_plan/README.md @@ -0,0 +1,58 @@ +backup_create_plan +================== + +A role to create a backup plan and optionally a vault. A set of variables for plan rules is included for use as-is or as examples for modification. This role can be combined with the backup_select_resources role to back up a selection of resources. + +Requirements +------------ + +AWS User Account with the following permission: + +* backup:CreateBackupVault +* backup:CreateBackupPlan +* backup:DescribeBackupVault +* backup:ListBackupPlans +* backup:ListTags +* backup-storage:MountCapsule +* kms:CreateGrant +* kms:GenerateDataKey +* kms:Decrypt +* kms:RetireGrant +* kms:DescribeKey + +Role Variables +-------------- + +* **plan_name**: (Required) The name of the backup plan you want to create +* **plan_rules**: (Required) A set of rules for the backup, as a list of dicts +* **plan_windows_vss_settings**: Optional settings for Windows VSS backup, see [AdvancedBackupSetting object in the AWS Backup API documentation](https://docs.aws.amazon.com/aws-backup/latest/devguide/API_AdvancedBackupSetting.html) for details +* **plan_tags**: Optional tags to apply to all backups created with the plan +* **vault_name**: The name of the vault you want to use or create. If not provided, will use the default backup vault for the account +* **vault_encryption_key_arn**: Optional ARN of key to use for vault encryption +* **vault_tags**: Optional tags to apply to the vault + +Dependencies +------------ + +* role: [aws_setup_credentials](../aws_setup_credentials/README.md) + +Example Playbook +---------------- + + - hosts: localhost + roles: + - role: cloud.aws_ops.backup_create_plan + plan_name: my-backup-plan + plan_rules: "{{ daily_backup }}" + +License +------- + +GNU General Public License v3.0 or later + +See [LICENCE](https://github.com/ansible-collections/cloud.aws_ops/blob/main/LICENSE) to see the full text. + +Author Information +------------------ + +* Ansible Cloud Content Team diff --git a/roles/backup_create_plan/defaults/main.yaml b/roles/backup_create_plan/defaults/main.yaml new file mode 100644 index 00000000..e99718f9 --- /dev/null +++ b/roles/backup_create_plan/defaults/main.yaml @@ -0,0 +1,7 @@ +--- +vault_name: Default +vault_encryption_key_arn: +vault_tags: + +plan_windows_vss_settings: +plan_tags: diff --git a/roles/backup_create_plan/meta/main.yaml b/roles/backup_create_plan/meta/main.yaml new file mode 100644 index 00000000..e8b3ab42 --- /dev/null +++ b/roles/backup_create_plan/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - role: cloud.aws_ops.aws_setup_credentials diff --git a/roles/backup_create_plan/tasks/main.yaml b/roles/backup_create_plan/tasks/main.yaml new file mode 100644 index 00000000..b961e11a --- /dev/null +++ b/roles/backup_create_plan/tasks/main.yaml @@ -0,0 +1,54 @@ +--- +- name: Verify required variables + block: + - name: Fail when plan variables are not defined + ansible.builtin.fail: + msg: "Required variable {{item}} has not been defined" + when: vars[item] is undefined + loop: + - plan_name + - plan_rules + +- name: Run backup_create_plan_role + module_defaults: + group/aws: "{{ aws_role_credentials }}" + block: + - name: Create or update backup vault if provided + when: vault_name != "Default" + block: + - name: Create or update backup vault + amazon.aws.backup_vault: + state: present + backup_vault_name: "{{ vault_name }}" + encryption_key_arn: "{{ vault_encryption_key_arn }}" + tags: "{{ vault_tags }}" + register: backup_vault_result + + - name: Verify that vault has been created/updated + ansible.builtin.debug: + msg: Vault '{{ vault_name }}' successfully created/updated. + when: backup_vault_result is changed + + - name: Verify that vault already exists + ansible.builtin.debug: + msg: Vault '{{ vault_name }}' exists, no updates needed. + when: backup_vault_result is not changed + + - name: Create or update backup plan + amazon.aws.backup_plan: + state: present + backup_plan_name: "{{ plan_name }}" + rules: "{{ plan_rules }}" + advanced_backup_settings: "{{ plan_windows_vss_settings }}" + tags: "{{ plan_tags }}" + register: backup_plan_result + + - name: Verify that plan has been created/updated + ansible.builtin.debug: + msg: Plan '{{ plan_name }}' successfully created/updated. + when: backup_plan_result is changed + + - name: Verify that plan already exists + ansible.builtin.debug: + msg: Plan '{{ plan_name }}' exists, no updates needed. + when: backup_plan_result is not changed diff --git a/roles/backup_create_plan/vars/main.yaml b/roles/backup_create_plan/vars/main.yaml new file mode 100644 index 00000000..07e1a421 --- /dev/null +++ b/roles/backup_create_plan/vars/main.yaml @@ -0,0 +1,30 @@ +--- +hourly_backup: # Hourly continous backup at :15 with 7-day retention + rule_name: hourly + target_backup_vault_name: "{{ vault_name }}" + schedule_expression: "cron(15 * ? * * *)" + start_window_minutes: 60 + completion_window_minutes: 120 + enable_continuous_backup: true + lifecycle: + delete_after_days: 7 + +daily_backup: # Daily backup at 5am UTC with Amazon defaults for all other settings + rule_name: daily + target_backup_vault_name: "{{ vault_name }}" + schedule_expression: "cron(0 5 ? * * *)" + +weekly_backup: # Weekly backup on Mondays at 5am UTC with 90 day retention after quick transition to cold storage + rule_name: weekly + target_backup_vault_name: "{{ vault_name }}" + schedule_expression: "cron(0 5 ? * MON *)" + lifecycle: + delete_after_days: 91 + move_to_cold_storage_after_days: 1 + +monthly_backup: # Monthly backup at 5am UTC on 1st of month with copy to additional vault + rule_name: monthly + target_backup_vault_name: "{{ vault_name }}" + schedule_expression: "cron(0 5 1 * ? *)" + copy_actions: + - destination_backup_vault_name: "{{ copy_vault_name }}" diff --git a/roles/backup_select_resources/README.md b/roles/backup_select_resources/README.md new file mode 100644 index 00000000..fa577045 --- /dev/null +++ b/roles/backup_select_resources/README.md @@ -0,0 +1,52 @@ +backup_select_resources +================== + +A role to configure backups for selected resources. The role requires an existing backup vault and plan, and adds selected resources to the provided plan. A set of variables for resource selections is included for use as-is or as examples for modification. This role can be combined with the backup_plan_create role to create or update a backup plan if one does not already exist. + +Requirements +------------ + +AWS User Account with the following permission: + +* backup:CreateBackupSelection +* backup:ListBackupSelections + +Role Variables +-------------- + +* **plan_name**: (Required) The name of the backup plan you want to use for the selected resources. +* **selection_name**: (Required) The display name of the resource selection you want to back up. +* **selection_resources**: (Required) List of resources selected for backup. Can use wild cards and/or combine with selection options below to precisely restrict resources based on various conditions. See included vars for examples. +* **selection_excluded_resources**: List of resources to exclude from backup +* **selection_tags**: List of resource tags selected for backup +* **selection_conditions**: Conditions for resources to back up +* **backup_role_name**: The name of an IAM role with permissions to perform all needed backup actions for the selected resources. If not provided, the role will use the AWSBackupDefaultServiceRole for the account (note: this will fail if the default role has not been created in the AWS console). + +Dependencies +------------ + +* role: [aws_setup_credentials](../aws_setup_credentials/README.md) + +Example Playbook +---------------- + + - hosts: localhost + roles: + - role: cloud.aws_ops.backup_select_resources + vars: + plan_name: daily-backup + selection_name: s3_buckets + selection_resources: + - "{{ all_s3_buckets }}" + +License +------- + +GNU General Public License v3.0 or later + +See [LICENCE](https://github.com/ansible-collections/cloud.aws_ops/blob/main/LICENSE) to see the full text. + +Author Information +------------------ + +* Ansible Cloud Content Team diff --git a/roles/backup_select_resources/defaults/main.yaml b/roles/backup_select_resources/defaults/main.yaml new file mode 100644 index 00000000..fd7de264 --- /dev/null +++ b/roles/backup_select_resources/defaults/main.yaml @@ -0,0 +1,6 @@ +--- +backup_role_name: AWSBackupDefaultServiceRole + +selection_excluded_resources: +selection_tags: +selection_conditions: diff --git a/roles/backup_select_resources/meta/main.yaml b/roles/backup_select_resources/meta/main.yaml new file mode 100644 index 00000000..e8b3ab42 --- /dev/null +++ b/roles/backup_select_resources/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - role: cloud.aws_ops.aws_setup_credentials diff --git a/roles/backup_select_resources/tasks/main.yaml b/roles/backup_select_resources/tasks/main.yaml new file mode 100644 index 00000000..a580a97f --- /dev/null +++ b/roles/backup_select_resources/tasks/main.yaml @@ -0,0 +1,60 @@ +--- +- name: Run backup_select_resources role + module_defaults: + group/aws: "{{ aws_role_credentials }}" + block: + - name: Fail when name and resource variables are not defined + ansible.builtin.fail: + msg: "Required variable {{item}} has not been defined" + when: vars[item] is undefined + loop: + - plan_name + - selection_name + - selection_resources + + - name: Get plan info + amazon.aws.backup_plan_info: + backup_plan_names: + - "{{ plan_name }}" + register: backup_plan_info + + - name: Fail when backup plan does not exist + ansible.builtin.fail: + msg: Backup plan {{ plan_name }} does not exist, please create or confirm plan name is correct. + when: backup_plan_info.backup_plans | length == 0 + + - name: Get provided IAM role info + community.aws.iam_role_info: + name: "{{ backup_role_name }}" + register: role_info + + - name: Fail when IAM role does not exist + ansible.builtin.fail: + msg: IAM role {{ backup_role_name }} does not exist, please create or confirm role name is correct. + when: role_info.iam_roles | length == 0 + + - name: Set backup role ARN + ansible.builtin.set_fact: + backup_role_arn: "{{ role_info.iam_roles[0].arn }}" + + - name: Create or update backup selection + amazon.aws.backup_selection: + state: present + backup_plan_name: "{{ plan_name }}" + selection_name: "{{ selection_name }}" + iam_role_arn: "{{ backup_role_arn }}" + resources: "{{ selection_resources }}" + list_of_tags: "{{ selection_tags }}" + not_resources: "{{ selection_excluded_resources }}" + conditions: "{{ selection_conditions }}" + register: selection_result + + - name: Verify that selection has been created/updated + ansible.builtin.debug: + msg: Backup selection '{{ selection_name }}' successfully created/updated. + when: selection_result is changed + + - name: Verify that selection already exists + ansible.builtin.debug: + msg: Backup selection '{{ selection_name }}' exists, no updates needed. + when: selection_result is not changed diff --git a/roles/backup_select_resources/vars/main.yaml b/roles/backup_select_resources/vars/main.yaml new file mode 100644 index 00000000..da723494 --- /dev/null +++ b/roles/backup_select_resources/vars/main.yaml @@ -0,0 +1,19 @@ +--- +all_resources: "*" +all_s3_buckets: "arn:aws:s3:::*" +all_rds_db_instances: "arn:aws:rds:*:*:db:*" + +tag_list_backup_or_prod: # Resources tagged {"backup": "true"} OR {"env": "prod"} + - condition_type: "STRINGEQUALS" + condition_key: "backup" + condition_value: "true" + - condition_type: "StringEquals" + condition_key: "env" + condition_value: "prod" + +conditions_tagged_backup_and_prod: # Resources tagged {"backup": "true"} AND {"env": "prod"} + string_equals: + - condition_key: "aws:ResourceTag/backup" + condition_value: "true" + - condition_key: "aws:ResourceTag/env" + condition_value: "prod" diff --git a/tests/integration/targets/test_backup_create_plan/defaults/main.yml b/tests/integration/targets/test_backup_create_plan/defaults/main.yml new file mode 100644 index 00000000..01f3dffd --- /dev/null +++ b/tests/integration/targets/test_backup_create_plan/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# defaults file for tests/integration/targets/test_backup_create_plan diff --git a/tests/integration/targets/test_backup_create_plan/tasks/main.yml b/tests/integration/targets/test_backup_create_plan/tasks/main.yml new file mode 100644 index 00000000..7307e268 --- /dev/null +++ b/tests/integration/targets/test_backup_create_plan/tasks/main.yml @@ -0,0 +1,125 @@ +--- +- name: Set 'test_resource_prefix' variable + ansible.builtin.set_fact: + test_resource_prefix: backup-resource-test-{{ 101 | random(1, 10) }} + +- name: Integration tests for 'backup_create_plan' role + module_defaults: + group/aws: + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" + + block: + - name: Set plan name variable + ansible.builtin.set_fact: + plan_name: "{{ test_resource_prefix }}-plan" + + - name: Include 'backup_create_plan' role to create plan with default vault + ansible.builtin.include_role: + name: cloud.aws_ops.backup_create_plan + vars: + plan_rules: + - "{{ daily_backup }}" + + - name: Get backup plan info + amazon.aws.backup_plan_info: + backup_plan_names: ["{{ plan_name }}"] + register: plan_create_result + + - name: Verify plan create result + ansible.builtin.assert: + that: + - plan_create_result.backup_plans | length == 1 + - plan_create_result.backup_plans[0].backup_plan_name == plan_name + - plan_create_result.backup_plans[0].backup_plan.rules | length == 1 + - plan_create_result.backup_plans[0].backup_plan.rules[0].rule_name == "daily" + - not plan_create_result.backup_plans[0].tags + + - name: Set vault name variable + ansible.builtin.set_fact: + vault_name: "{{ test_resource_prefix }}-vault" + + - name: Include 'backup_create_plan' role to create vault and plan + ansible.builtin.include_role: + name: cloud.aws_ops.backup_create_plan + vars: + plan_rules: + - "{{ weekly_backup }}" + + - name: Get backup vault info + amazon.aws.backup_vault_info: + backup_vault_names: ["{{ vault_name }}"] + register: vault_create_result + + - name: Verify vault create result + ansible.builtin.assert: + that: + - vault_create_result.backup_vaults | length == 1 + - vault_create_result.backup_vaults[0].backup_vault_name == vault_name + - not vault_create_result.backup_vaults[0].tags + + - name: Get backup plan info + amazon.aws.backup_plan_info: + backup_plan_names: ["{{ plan_name }}"] + register: plan_create_result + + - name: Verify plan create result + ansible.builtin.assert: + that: + - plan_create_result.backup_plans | length == 1 + - plan_create_result.backup_plans[0].backup_plan_name == plan_name + - plan_create_result.backup_plans[0].backup_plan.rules | length == 1 + - plan_create_result.backup_plans[0].backup_plan.rules[0].rule_name == "weekly" + - not plan_create_result.backup_plans[0].tags + + - name: Include 'backup_create_plan' role to update vault and plan + ansible.builtin.include_role: + name: cloud.aws_ops.backup_create_plan + vars: + vault_tags: + environment: test + plan_rules: + - "{{ hourly_backup }}" + plan_tags: + environment: test + + - name: Get backup vault info + amazon.aws.backup_vault_info: + backup_vault_names: ["{{ vault_name }}"] + register: vault_update_result + + - name: Verify vault update result + ansible.builtin.assert: + that: + - vault_update_result.backup_vaults | length == 1 + - vault_update_result.backup_vaults[0].backup_vault_name == vault_name + - vault_update_result.backup_vaults[0].tags.environment == "test" + + - name: Get backup plan info + amazon.aws.backup_plan_info: + backup_plan_names: ["{{ plan_name }}"] + register: plan_update_result + + - name: Verify plan update result + ansible.builtin.assert: + that: + - plan_update_result.backup_plans | length == 1 + - plan_update_result.backup_plans[0].backup_plan_name == plan_name + - plan_update_result.backup_plans[0].backup_plan.rules | length == 1 + - plan_update_result.backup_plans[0].backup_plan.rules[0].rule_name == "hourly" + - plan_update_result.backup_plans[0].tags.environment == "test" + + always: + - name: Delete backup plan created for test + amazon.aws.backup_plan: + backup_plan_name: "{{ plan_name }}" + state: absent + ignore_errors: true + + - name: Delete backup vault created for test + amazon.aws.backup_vault: + backup_vault_name: "{{ vault_name }}" + state: absent + ignore_errors: true diff --git a/tests/integration/targets/test_backup_select_resources/defaults/main.yml b/tests/integration/targets/test_backup_select_resources/defaults/main.yml new file mode 100644 index 00000000..7eb32b45 --- /dev/null +++ b/tests/integration/targets/test_backup_select_resources/defaults/main.yml @@ -0,0 +1,6 @@ +--- +plan_name: "{{ test_resource_prefix }}-plan" +selection_name: "{{ test_resource_prefix }}-selection" +selection_two: "{{ test_resource_prefix }}-selection-2" +test_iam_role_name: "{{ test_resource_prefix }}-iam-role" +test_vault_name: "{{ test_resource_prefix }}-vault" diff --git a/tests/integration/targets/test_backup_select_resources/files/backup-policy.json b/tests/integration/targets/test_backup_select_resources/files/backup-policy.json new file mode 100644 index 00000000..c8c34812 --- /dev/null +++ b/tests/integration/targets/test_backup_select_resources/files/backup-policy.json @@ -0,0 +1,12 @@ +{ + "Version": "2012-10-17", + "Statement":[ + { + "Effect": "Allow", + "Principal": { + "Service": "backup.amazonaws.com" + }, + "Action": "sts:AssumeRole" + } + ] +} diff --git a/tests/integration/targets/test_backup_select_resources/tasks/main.yml b/tests/integration/targets/test_backup_select_resources/tasks/main.yml new file mode 100644 index 00000000..114a1bad --- /dev/null +++ b/tests/integration/targets/test_backup_select_resources/tasks/main.yml @@ -0,0 +1,106 @@ +--- +- name: Set 'test_resource_prefix' variable + ansible.builtin.set_fact: + test_resource_prefix: backup-resource-test-{{ 101 | random(1, 10) }} + +- name: Integration tests for 'backup_create_vault' role + module_defaults: + group/aws: + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" + + block: + - name: Include 'setup.yml' file + ansible.builtin.include_tasks: setup.yml + + - name: Include 'backup_select_resources' role for all resources using provided role + ansible.builtin.include_role: + name: cloud.aws_ops.backup_select_resources + vars: + backup_role_name: "{{ test_iam_role_name }}" + selection_resources: + - "{{ all_resources }}" + + - name: Get backup selection info + amazon.aws.backup_selection_info: + backup_plan_name: "{{ plan_name }}" + register: result + + - name: Verify result + ansible.builtin.assert: + that: + - result.backup_selections | length == 1 + - result.backup_selections[0].selection_name == selection_name + - result.backup_selections[0].resources == ["*"] + + - name: Include 'backup_select_resources' role for all resources using default role + ansible.builtin.include_role: + name: cloud.aws_ops.backup_select_resources + vars: + selection_resources: + - "{{ all_resources }}" + + - name: Get backup selection info + amazon.aws.backup_selection_info: + backup_plan_name: "{{ plan_name }}" + register: result + + - name: Verify result + ansible.builtin.assert: + that: + - result.backup_selections | length == 1 + - result.backup_selections[0].selection_name == selection_name + - result.backup_selections[0].resources == ["*"] + + - name: Include 'backup_select_resources' role updating selection to all s3 buckets with specified tags + ansible.builtin.include_role: + name: cloud.aws_ops.backup_select_resources + vars: + selection_resources: + - "{{ all_s3_buckets }}" + selection_tags: "{{ tag_list_backup_or_prod }}" + + - name: Get updated backup selection info + amazon.aws.backup_selection_info: + backup_plan_name: "{{ plan_name }}" + register: result + + - name: Verify result + ansible.builtin.assert: + that: + - result.backup_selections | length == 1 + - result.backup_selections[0].selection_name == selection_name + - result.backup_selections[0].resources == ["arn:aws:s3:::*"] + - result.backup_selections[0].list_of_tags | length == 2 + + - name: Include 'backup_select_resources' role adding selection of all resources except rds instances with specified conditions + ansible.builtin.include_role: + name: cloud.aws_ops.backup_select_resources + vars: + selection_name: "{{ selection_two }}" + selection_resources: + - "{{ all_resources }}" + selection_excluded_resources: + - "{{ all_rds_db_instances }}" + selection_conditions: "{{ conditions_tagged_backup_and_prod }}" + + - name: Get updated backup selection info + amazon.aws.backup_selection_info: + backup_plan_name: "{{ plan_name }}" + register: result + + - name: Verify result + ansible.builtin.assert: + that: + - result.backup_selections | length == 2 + - result.backup_selections[1].selection_name == "{{ selection_two }}" + - result.backup_selections[1].resources == ["*"] + - result.backup_selections[1].not_resources == ["arn:aws:rds:*:*:db:*"] + - result.backup_selections[1].list_of_tags | length == 0 + - result.backup_selections[1].conditions.string_equals | length == 2 + + always: + - name: Include 'teardown.yml' file + ansible.builtin.include_tasks: teardown.yml diff --git a/tests/integration/targets/test_backup_select_resources/tasks/setup.yml b/tests/integration/targets/test_backup_select_resources/tasks/setup.yml new file mode 100644 index 00000000..b5db7b63 --- /dev/null +++ b/tests/integration/targets/test_backup_select_resources/tasks/setup.yml @@ -0,0 +1,24 @@ +--- +- name: Create an IAM Role for backup + community.aws.iam_role: + name: "{{ test_iam_role_name }}" + state: present + assume_role_policy_document: '{{ lookup("file", "backup-policy.json") }}' + create_instance_profile: false + description: "Test Ansible AWS Backup Role" + managed_policy: + - "arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForBackup" + wait: true + register: iam_role + +- name: Wait for role to be created + ansible.builtin.pause: + seconds: 8 + +- name: Create a backup vault and plan for test + ansible.builtin.include_role: + name: cloud.aws_ops.backup_create_plan + vars: + vault_name: "{{ test_vault_name }}" + plan_rules: + - "{{ daily_backup }}" diff --git a/tests/integration/targets/test_backup_select_resources/tasks/teardown.yml b/tests/integration/targets/test_backup_select_resources/tasks/teardown.yml new file mode 100644 index 00000000..26a56e7f --- /dev/null +++ b/tests/integration/targets/test_backup_select_resources/tasks/teardown.yml @@ -0,0 +1,34 @@ +--- +- name: Delete backup selection created for test + amazon.aws.backup_selection: + state: absent + backup_plan_name: "{{ plan_name }}" + selection_name: "{{ selection_name }}" + ignore_errors: true + +- name: Delete backup selection two created for test + amazon.aws.backup_selection: + state: absent + backup_plan_name: "{{ plan_name }}" + selection_name: "{{ selection_two }}" + ignore_errors: true + +- name: Delete backup plan created for test + amazon.aws.backup_plan: + backup_plan_name: "{{ plan_name }}" + state: absent + ignore_errors: true + +- name: Delete backup vault created for test + amazon.aws.backup_vault: + backup_vault_name: "{{ test_vault_name }}" + state: absent + ignore_errors: true + +- name: Delete IAM role created for test + community.aws.iam_role: + name: "{{ test_iam_role_name }}" + state: absent + wait: true + wait_timeout: 30 + ignore_errors: true From b2d6cccdae54186287341781e3124471357f22d2 Mon Sep 17 00:00:00 2001 From: Helen Bailey Date: Fri, 30 Jun 2023 14:32:28 -0400 Subject: [PATCH 03/11] Update permission requirements in backup_select_resources README --- roles/backup_select_resources/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/roles/backup_select_resources/README.md b/roles/backup_select_resources/README.md index fa577045..0c0db0b9 100644 --- a/roles/backup_select_resources/README.md +++ b/roles/backup_select_resources/README.md @@ -9,7 +9,11 @@ Requirements AWS User Account with the following permission: * backup:CreateBackupSelection +* backup:DeleteBackupSelection +* backup:GetBackupPlan +* backup:GetBackupSelection * backup:ListBackupSelections +* iam:GetRole Role Variables -------------- From 3f100706b986f4a8dc057aef127f0008727e7871 Mon Sep 17 00:00:00 2001 From: Helen Bailey Date: Mon, 3 Jul 2023 14:12:09 -0400 Subject: [PATCH 04/11] Update README --- roles/backup_create_plan/README.md | 11 ++++++++++- roles/backup_select_resources/README.md | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/roles/backup_create_plan/README.md b/roles/backup_create_plan/README.md index 9c2098b3..a4bacc4f 100644 --- a/roles/backup_create_plan/README.md +++ b/roles/backup_create_plan/README.md @@ -27,10 +27,19 @@ Role Variables * **plan_rules**: (Required) A set of rules for the backup, as a list of dicts * **plan_windows_vss_settings**: Optional settings for Windows VSS backup, see [AdvancedBackupSetting object in the AWS Backup API documentation](https://docs.aws.amazon.com/aws-backup/latest/devguide/API_AdvancedBackupSetting.html) for details * **plan_tags**: Optional tags to apply to all backups created with the plan -* **vault_name**: The name of the vault you want to use or create. If not provided, will use the default backup vault for the account +* **vault_name**: The name of the vault you want to use or create. If not provided, will use the default backup vault for the account (note: the Default vault must be created in the AWS console when initially enabling the AWS Backup Service.) * **vault_encryption_key_arn**: Optional ARN of key to use for vault encryption * **vault_tags**: Optional tags to apply to the vault +### Included sample plan rules variables +These are included in vars/main.yaml for use as-is or as examples for modification. + +* **hourly_backup**: Rules specifying hourly continous backup at :15 UTC with 7-day retention +* **daily_backup**: Rules specifying daily backup at 5am UTC with Amazon defaults for all other settings +* **weekly_backup**: Rules specifying weekly backup on Mondays at 5am UTC with 90 day retention after quick transition to cold storage +* **monthly_backup**: Rules specifying monthly backup at 5am UTC on 1st of month with copy to additional vault (requires an additional variable **copy_vault_name** be set with the name of the vault to copy to) + + Dependencies ------------ diff --git a/roles/backup_select_resources/README.md b/roles/backup_select_resources/README.md index 0c0db0b9..96af5d98 100644 --- a/roles/backup_select_resources/README.md +++ b/roles/backup_select_resources/README.md @@ -24,7 +24,16 @@ Role Variables * **selection_excluded_resources**: List of resources to exclude from backup * **selection_tags**: List of resource tags selected for backup * **selection_conditions**: Conditions for resources to back up -* **backup_role_name**: The name of an IAM role with permissions to perform all needed backup actions for the selected resources. If not provided, the role will use the AWSBackupDefaultServiceRole for the account (note: this will fail if the default role has not been created in the AWS console). +* **backup_role_name**: The name of an IAM role with permissions to perform all needed backup actions for the selected resources. If not provided, the role will use the AWSBackupDefaultServiceRole for the account (note: the AWSBackupDefaultServiceRole role must be created in the AWS console when initially enabling the AWS Backup Service.) + +### Included sample resource selection variables +These are included in vars/main.yaml for use as-is or as examples for modification. + +* **all_resources**: All AWS resources +* **all_s3_buckets** All S3 buckets +* **all_rds_db_instances**: All RDS database instances +* **tag_list_backup_or_prod**: Resources tagged {"backup": "true"} OR {"env": "prod"}, for use with the **selection_tags** role variable +* **conditions_tagged_backup_and_prod**: Resources tagged {"backup": "true"} AND {"env": "prod"}, for use with the **selection_conditions** role variable Dependencies ------------ From 27d7796c55cb077213504774aa03c6b03afafd61 Mon Sep 17 00:00:00 2001 From: Helen Bailey Date: Mon, 3 Jul 2023 14:24:26 -0400 Subject: [PATCH 05/11] Update default variables --- roles/backup_create_plan/defaults/main.yaml | 5 ---- roles/backup_create_plan/tasks/main.yaml | 8 +++---- .../defaults/main.yaml | 4 ---- roles/backup_select_resources/tasks/main.yaml | 24 +++++++++---------- 4 files changed, 16 insertions(+), 25 deletions(-) diff --git a/roles/backup_create_plan/defaults/main.yaml b/roles/backup_create_plan/defaults/main.yaml index e99718f9..2d311b4c 100644 --- a/roles/backup_create_plan/defaults/main.yaml +++ b/roles/backup_create_plan/defaults/main.yaml @@ -1,7 +1,2 @@ --- vault_name: Default -vault_encryption_key_arn: -vault_tags: - -plan_windows_vss_settings: -plan_tags: diff --git a/roles/backup_create_plan/tasks/main.yaml b/roles/backup_create_plan/tasks/main.yaml index b961e11a..b30dc60c 100644 --- a/roles/backup_create_plan/tasks/main.yaml +++ b/roles/backup_create_plan/tasks/main.yaml @@ -20,8 +20,8 @@ amazon.aws.backup_vault: state: present backup_vault_name: "{{ vault_name }}" - encryption_key_arn: "{{ vault_encryption_key_arn }}" - tags: "{{ vault_tags }}" + encryption_key_arn: "{{ vault_encryption_key_arn | default(omit) }}" + tags: "{{ vault_tags | default(omit) }}" register: backup_vault_result - name: Verify that vault has been created/updated @@ -39,8 +39,8 @@ state: present backup_plan_name: "{{ plan_name }}" rules: "{{ plan_rules }}" - advanced_backup_settings: "{{ plan_windows_vss_settings }}" - tags: "{{ plan_tags }}" + advanced_backup_settings: "{{ plan_windows_vss_settings | default(omit) }}" + tags: "{{ plan_tags | default(omit) }}" register: backup_plan_result - name: Verify that plan has been created/updated diff --git a/roles/backup_select_resources/defaults/main.yaml b/roles/backup_select_resources/defaults/main.yaml index fd7de264..712342d9 100644 --- a/roles/backup_select_resources/defaults/main.yaml +++ b/roles/backup_select_resources/defaults/main.yaml @@ -1,6 +1,2 @@ --- backup_role_name: AWSBackupDefaultServiceRole - -selection_excluded_resources: -selection_tags: -selection_conditions: diff --git a/roles/backup_select_resources/tasks/main.yaml b/roles/backup_select_resources/tasks/main.yaml index a580a97f..92a05f1b 100644 --- a/roles/backup_select_resources/tasks/main.yaml +++ b/roles/backup_select_resources/tasks/main.yaml @@ -1,17 +1,17 @@ --- +- name: Fail when name and resource variables are not defined + ansible.builtin.fail: + msg: "Required variable {{item}} has not been defined" + when: vars[item] is undefined + loop: + - plan_name + - selection_name + - selection_resources + - name: Run backup_select_resources role module_defaults: group/aws: "{{ aws_role_credentials }}" block: - - name: Fail when name and resource variables are not defined - ansible.builtin.fail: - msg: "Required variable {{item}} has not been defined" - when: vars[item] is undefined - loop: - - plan_name - - selection_name - - selection_resources - - name: Get plan info amazon.aws.backup_plan_info: backup_plan_names: @@ -44,9 +44,9 @@ selection_name: "{{ selection_name }}" iam_role_arn: "{{ backup_role_arn }}" resources: "{{ selection_resources }}" - list_of_tags: "{{ selection_tags }}" - not_resources: "{{ selection_excluded_resources }}" - conditions: "{{ selection_conditions }}" + list_of_tags: "{{ selection_tags | default(omit) }}" + not_resources: "{{ selection_excluded_resources | default(omit) }}" + conditions: "{{ selection_conditions | default(omit) }}" register: selection_result - name: Verify that selection has been created/updated From a97ff948009f56e06ee843389606c063431589f3 Mon Sep 17 00:00:00 2001 From: Helen Bailey Date: Mon, 3 Jul 2023 18:01:12 -0400 Subject: [PATCH 06/11] Update configuration for integration tests --- tests/integration/constraints.txt | 7 +++++++ tests/integration/requirements.txt | 3 +++ tests/integration/targets/test_backup_create_plan/aliases | 3 +++ .../targets/test_backup_select_resources/aliases | 3 +++ 4 files changed, 16 insertions(+) create mode 100644 tests/integration/constraints.txt create mode 100644 tests/integration/requirements.txt create mode 100644 tests/integration/targets/test_backup_create_plan/aliases create mode 100644 tests/integration/targets/test_backup_select_resources/aliases diff --git a/tests/integration/constraints.txt b/tests/integration/constraints.txt new file mode 100644 index 00000000..927a6f07 --- /dev/null +++ b/tests/integration/constraints.txt @@ -0,0 +1,7 @@ +# Specifically run tests against the oldest versions that we support +boto3==1.22.0 +botocore==1.25.0 + +# AWS CLI has `botocore==` dependencies, provide the one that matches botocore +# to avoid needing to download over a years worth of awscli wheels. +awscli==1.23.0 diff --git a/tests/integration/requirements.txt b/tests/integration/requirements.txt new file mode 100644 index 00000000..1d40e8f9 --- /dev/null +++ b/tests/integration/requirements.txt @@ -0,0 +1,3 @@ +# Our code is based on the AWS SDKs +boto3 +botocore diff --git a/tests/integration/targets/test_backup_create_plan/aliases b/tests/integration/targets/test_backup_create_plan/aliases new file mode 100644 index 00000000..f73b35a4 --- /dev/null +++ b/tests/integration/targets/test_backup_create_plan/aliases @@ -0,0 +1,3 @@ +cloud/aws +role/backup_create_plan +time=3m diff --git a/tests/integration/targets/test_backup_select_resources/aliases b/tests/integration/targets/test_backup_select_resources/aliases new file mode 100644 index 00000000..7b05d295 --- /dev/null +++ b/tests/integration/targets/test_backup_select_resources/aliases @@ -0,0 +1,3 @@ +cloud/aws +role/backup_select_resources +time=3m From 2d83ef3c81c6dd2f8e5b68eebd5837e7ff9526c4 Mon Sep 17 00:00:00 2001 From: Helen Bailey Date: Mon, 3 Jul 2023 18:08:23 -0400 Subject: [PATCH 07/11] Update tests for new CI config --- .../test_backup_create_plan/defaults/main.yml | 2 +- .../targets/test_backup_create_plan/tasks/main.yml | 8 ++------ .../test_backup_select_resources/defaults/main.yml | 12 +++++++----- .../test_backup_select_resources/tasks/main.yml | 4 ---- 4 files changed, 10 insertions(+), 16 deletions(-) diff --git a/tests/integration/targets/test_backup_create_plan/defaults/main.yml b/tests/integration/targets/test_backup_create_plan/defaults/main.yml index 01f3dffd..ad1e2410 100644 --- a/tests/integration/targets/test_backup_create_plan/defaults/main.yml +++ b/tests/integration/targets/test_backup_create_plan/defaults/main.yml @@ -1,2 +1,2 @@ --- -# defaults file for tests/integration/targets/test_backup_create_plan +aws_security_token: '{{ security_token | default(omit) }}' diff --git a/tests/integration/targets/test_backup_create_plan/tasks/main.yml b/tests/integration/targets/test_backup_create_plan/tasks/main.yml index 7307e268..f226b95a 100644 --- a/tests/integration/targets/test_backup_create_plan/tasks/main.yml +++ b/tests/integration/targets/test_backup_create_plan/tasks/main.yml @@ -1,8 +1,4 @@ --- -- name: Set 'test_resource_prefix' variable - ansible.builtin.set_fact: - test_resource_prefix: backup-resource-test-{{ 101 | random(1, 10) }} - - name: Integration tests for 'backup_create_plan' role module_defaults: group/aws: @@ -14,7 +10,7 @@ block: - name: Set plan name variable ansible.builtin.set_fact: - plan_name: "{{ test_resource_prefix }}-plan" + plan_name: "{{ resource_prefix }}-plan" - name: Include 'backup_create_plan' role to create plan with default vault ansible.builtin.include_role: @@ -39,7 +35,7 @@ - name: Set vault name variable ansible.builtin.set_fact: - vault_name: "{{ test_resource_prefix }}-vault" + vault_name: "{{ resource_prefix }}-vault" - name: Include 'backup_create_plan' role to create vault and plan ansible.builtin.include_role: diff --git a/tests/integration/targets/test_backup_select_resources/defaults/main.yml b/tests/integration/targets/test_backup_select_resources/defaults/main.yml index 7eb32b45..df153d73 100644 --- a/tests/integration/targets/test_backup_select_resources/defaults/main.yml +++ b/tests/integration/targets/test_backup_select_resources/defaults/main.yml @@ -1,6 +1,8 @@ --- -plan_name: "{{ test_resource_prefix }}-plan" -selection_name: "{{ test_resource_prefix }}-selection" -selection_two: "{{ test_resource_prefix }}-selection-2" -test_iam_role_name: "{{ test_resource_prefix }}-iam-role" -test_vault_name: "{{ test_resource_prefix }}-vault" +aws_security_token: '{{ security_token | default(omit) }}' +plan_name: "{{ resource_prefix }}-plan" +selection_name: "{{ resource_prefix }}-selection" +selection_two: "{{ resource_prefix }}-selection-2" +test_iam_role_name: "{{ resource_prefix }}-iam-role" +test_iam_role_name: "{{ resource_prefix }}-iam-role-2" +test_vault_name: "{{ resource_prefix }}-vault" diff --git a/tests/integration/targets/test_backup_select_resources/tasks/main.yml b/tests/integration/targets/test_backup_select_resources/tasks/main.yml index 114a1bad..88874472 100644 --- a/tests/integration/targets/test_backup_select_resources/tasks/main.yml +++ b/tests/integration/targets/test_backup_select_resources/tasks/main.yml @@ -1,8 +1,4 @@ --- -- name: Set 'test_resource_prefix' variable - ansible.builtin.set_fact: - test_resource_prefix: backup-resource-test-{{ 101 | random(1, 10) }} - - name: Integration tests for 'backup_create_vault' role module_defaults: group/aws: From eb3062764a1d46627e3783130bf6877a6cb40589 Mon Sep 17 00:00:00 2001 From: Helen Bailey Date: Tue, 4 Jul 2023 16:38:55 -0400 Subject: [PATCH 08/11] Create Default vault and new IAM role if not present --- roles/backup_create_plan/README.md | 2 +- roles/backup_create_plan/tasks/main.yaml | 5 ++- roles/backup_select_resources/README.md | 2 +- .../defaults/main.yaml | 2 -- .../files/backup-policy.json | 12 +++++++ roles/backup_select_resources/tasks/main.yaml | 31 ++++++++++++++----- .../defaults/main.yml | 2 +- .../tasks/main.yml | 9 ++++-- .../tasks/teardown.yml | 8 +++++ 9 files changed, 54 insertions(+), 19 deletions(-) delete mode 100644 roles/backup_select_resources/defaults/main.yaml create mode 100644 roles/backup_select_resources/files/backup-policy.json diff --git a/roles/backup_create_plan/README.md b/roles/backup_create_plan/README.md index a4bacc4f..84e79404 100644 --- a/roles/backup_create_plan/README.md +++ b/roles/backup_create_plan/README.md @@ -27,7 +27,7 @@ Role Variables * **plan_rules**: (Required) A set of rules for the backup, as a list of dicts * **plan_windows_vss_settings**: Optional settings for Windows VSS backup, see [AdvancedBackupSetting object in the AWS Backup API documentation](https://docs.aws.amazon.com/aws-backup/latest/devguide/API_AdvancedBackupSetting.html) for details * **plan_tags**: Optional tags to apply to all backups created with the plan -* **vault_name**: The name of the vault you want to use or create. If not provided, will use the default backup vault for the account (note: the Default vault must be created in the AWS console when initially enabling the AWS Backup Service.) +* **vault_name**: The name of the vault you want to use or create. If not provided, the role will use (and create if needed) the AWS default vault for the account, named Default. * **vault_encryption_key_arn**: Optional ARN of key to use for vault encryption * **vault_tags**: Optional tags to apply to the vault diff --git a/roles/backup_create_plan/tasks/main.yaml b/roles/backup_create_plan/tasks/main.yaml index b30dc60c..f94fa28e 100644 --- a/roles/backup_create_plan/tasks/main.yaml +++ b/roles/backup_create_plan/tasks/main.yaml @@ -11,10 +11,9 @@ - name: Run backup_create_plan_role module_defaults: - group/aws: "{{ aws_role_credentials }}" + group/aws: "{{ aws_setup_credentials__output }}" block: - - name: Create or update backup vault if provided - when: vault_name != "Default" + - name: Create or update backup vault block: - name: Create or update backup vault amazon.aws.backup_vault: diff --git a/roles/backup_select_resources/README.md b/roles/backup_select_resources/README.md index 96af5d98..d4f9bb62 100644 --- a/roles/backup_select_resources/README.md +++ b/roles/backup_select_resources/README.md @@ -24,7 +24,7 @@ Role Variables * **selection_excluded_resources**: List of resources to exclude from backup * **selection_tags**: List of resource tags selected for backup * **selection_conditions**: Conditions for resources to back up -* **backup_role_name**: The name of an IAM role with permissions to perform all needed backup actions for the selected resources. If not provided, the role will use the AWSBackupDefaultServiceRole for the account (note: the AWSBackupDefaultServiceRole role must be created in the AWS console when initially enabling the AWS Backup Service.) +* **backup_role_name**: (Required) The name of an IAM role with permissions to perform all needed backup actions for the selected resources. Alternatively, provide a new for a new IAM role which will be created with the same permissions as the AWSBackupDefaultServiceRole (note: these permissions allow backups and restores for all resources). ### Included sample resource selection variables These are included in vars/main.yaml for use as-is or as examples for modification. diff --git a/roles/backup_select_resources/defaults/main.yaml b/roles/backup_select_resources/defaults/main.yaml deleted file mode 100644 index 712342d9..00000000 --- a/roles/backup_select_resources/defaults/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -backup_role_name: AWSBackupDefaultServiceRole diff --git a/roles/backup_select_resources/files/backup-policy.json b/roles/backup_select_resources/files/backup-policy.json new file mode 100644 index 00000000..c8c34812 --- /dev/null +++ b/roles/backup_select_resources/files/backup-policy.json @@ -0,0 +1,12 @@ +{ + "Version": "2012-10-17", + "Statement":[ + { + "Effect": "Allow", + "Principal": { + "Service": "backup.amazonaws.com" + }, + "Action": "sts:AssumeRole" + } + ] +} diff --git a/roles/backup_select_resources/tasks/main.yaml b/roles/backup_select_resources/tasks/main.yaml index 92a05f1b..79d91227 100644 --- a/roles/backup_select_resources/tasks/main.yaml +++ b/roles/backup_select_resources/tasks/main.yaml @@ -1,16 +1,17 @@ --- -- name: Fail when name and resource variables are not defined +- name: Fail when name, role, and resource variables are not defined ansible.builtin.fail: - msg: "Required variable {{item}} has not been defined" + msg: "Required variable {{ item }} has not been defined" when: vars[item] is undefined loop: + - backup_role_name - plan_name - selection_name - selection_resources - name: Run backup_select_resources role module_defaults: - group/aws: "{{ aws_role_credentials }}" + group/aws: "{{ aws_setup_credentials__output }}" block: - name: Get plan info amazon.aws.backup_plan_info: @@ -28,14 +29,28 @@ name: "{{ backup_role_name }}" register: role_info - - name: Fail when IAM role does not exist - ansible.builtin.fail: - msg: IAM role {{ backup_role_name }} does not exist, please create or confirm role name is correct. - when: role_info.iam_roles | length == 0 + - name: Create new role when IAM role does not exist + block: + - name: Create role + when: role_info.iam_roles | length == 0 + community.aws.iam_role: + name: "{{ backup_role_name }}" + state: present + assume_role_policy_document: '{{ lookup("file", "backup-policy.json") }}' + create_instance_profile: false + description: "AWS Backup Role" + managed_policy: + - arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForBackup + wait: true + register: new_role_info + + - name: Wait for role to be created + ansible.builtin.pause: + seconds: 8 - name: Set backup role ARN ansible.builtin.set_fact: - backup_role_arn: "{{ role_info.iam_roles[0].arn }}" + backup_role_arn: "{{ role_info.iam_roles[0].arn if new_role_info is skipped else new_role_info.arn }}" - name: Create or update backup selection amazon.aws.backup_selection: diff --git a/tests/integration/targets/test_backup_select_resources/defaults/main.yml b/tests/integration/targets/test_backup_select_resources/defaults/main.yml index df153d73..bb61b33d 100644 --- a/tests/integration/targets/test_backup_select_resources/defaults/main.yml +++ b/tests/integration/targets/test_backup_select_resources/defaults/main.yml @@ -4,5 +4,5 @@ plan_name: "{{ resource_prefix }}-plan" selection_name: "{{ resource_prefix }}-selection" selection_two: "{{ resource_prefix }}-selection-2" test_iam_role_name: "{{ resource_prefix }}-iam-role" -test_iam_role_name: "{{ resource_prefix }}-iam-role-2" +test_iam_role_name_new: "{{ resource_prefix }}-iam-role-new" test_vault_name: "{{ resource_prefix }}-vault" diff --git a/tests/integration/targets/test_backup_select_resources/tasks/main.yml b/tests/integration/targets/test_backup_select_resources/tasks/main.yml index 88874472..608de74e 100644 --- a/tests/integration/targets/test_backup_select_resources/tasks/main.yml +++ b/tests/integration/targets/test_backup_select_resources/tasks/main.yml @@ -11,11 +11,11 @@ - name: Include 'setup.yml' file ansible.builtin.include_tasks: setup.yml - - name: Include 'backup_select_resources' role for all resources using provided role + - name: Include 'backup_select_resources' role for all resources using new IAM role ansible.builtin.include_role: name: cloud.aws_ops.backup_select_resources vars: - backup_role_name: "{{ test_iam_role_name }}" + backup_role_name: "{{ test_iam_role_name_new }}" selection_resources: - "{{ all_resources }}" @@ -31,10 +31,11 @@ - result.backup_selections[0].selection_name == selection_name - result.backup_selections[0].resources == ["*"] - - name: Include 'backup_select_resources' role for all resources using default role + - name: Include 'backup_select_resources' role for all resources using existing IAM role ansible.builtin.include_role: name: cloud.aws_ops.backup_select_resources vars: + backup_role_name: "{{ test_iam_role_name }}" selection_resources: - "{{ all_resources }}" @@ -54,6 +55,7 @@ ansible.builtin.include_role: name: cloud.aws_ops.backup_select_resources vars: + backup_role_name: "{{ test_iam_role_name }}" selection_resources: - "{{ all_s3_buckets }}" selection_tags: "{{ tag_list_backup_or_prod }}" @@ -75,6 +77,7 @@ ansible.builtin.include_role: name: cloud.aws_ops.backup_select_resources vars: + backup_role_name: "{{ test_iam_role_name }}" selection_name: "{{ selection_two }}" selection_resources: - "{{ all_resources }}" diff --git a/tests/integration/targets/test_backup_select_resources/tasks/teardown.yml b/tests/integration/targets/test_backup_select_resources/tasks/teardown.yml index 26a56e7f..335386a9 100644 --- a/tests/integration/targets/test_backup_select_resources/tasks/teardown.yml +++ b/tests/integration/targets/test_backup_select_resources/tasks/teardown.yml @@ -32,3 +32,11 @@ wait: true wait_timeout: 30 ignore_errors: true + +- name: Delete IAM role created during test + community.aws.iam_role: + name: "{{ test_iam_role_name_new }}" + state: absent + wait: true + wait_timeout: 30 + ignore_errors: true From 9fd681d45fc05ea625f0d0cba49b7cede36d66d4 Mon Sep 17 00:00:00 2001 From: Helen Bailey Date: Wed, 5 Jul 2023 08:58:57 -0400 Subject: [PATCH 09/11] Fix linting errors --- roles/backup_create_plan/vars/main.yaml | 8 ++++---- roles/backup_select_resources/vars/main.yaml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/roles/backup_create_plan/vars/main.yaml b/roles/backup_create_plan/vars/main.yaml index 07e1a421..1731a2fb 100644 --- a/roles/backup_create_plan/vars/main.yaml +++ b/roles/backup_create_plan/vars/main.yaml @@ -1,5 +1,5 @@ --- -hourly_backup: # Hourly continous backup at :15 with 7-day retention +hourly_backup: # Hourly continous backup at :15 with 7-day retention rule_name: hourly target_backup_vault_name: "{{ vault_name }}" schedule_expression: "cron(15 * ? * * *)" @@ -9,12 +9,12 @@ hourly_backup: # Hourly continous backup at :15 with 7-day retention lifecycle: delete_after_days: 7 -daily_backup: # Daily backup at 5am UTC with Amazon defaults for all other settings +daily_backup: # Daily backup at 5am UTC with Amazon defaults for all other settings rule_name: daily target_backup_vault_name: "{{ vault_name }}" schedule_expression: "cron(0 5 ? * * *)" -weekly_backup: # Weekly backup on Mondays at 5am UTC with 90 day retention after quick transition to cold storage +weekly_backup: # Weekly backup on Mondays at 5am UTC with 90 day retention after quick transition to cold storage rule_name: weekly target_backup_vault_name: "{{ vault_name }}" schedule_expression: "cron(0 5 ? * MON *)" @@ -22,7 +22,7 @@ weekly_backup: # Weekly backup on Mondays at 5am UTC with 90 day retention after delete_after_days: 91 move_to_cold_storage_after_days: 1 -monthly_backup: # Monthly backup at 5am UTC on 1st of month with copy to additional vault +monthly_backup: # Monthly backup at 5am UTC on 1st of month with copy to additional vault rule_name: monthly target_backup_vault_name: "{{ vault_name }}" schedule_expression: "cron(0 5 1 * ? *)" diff --git a/roles/backup_select_resources/vars/main.yaml b/roles/backup_select_resources/vars/main.yaml index da723494..837254ba 100644 --- a/roles/backup_select_resources/vars/main.yaml +++ b/roles/backup_select_resources/vars/main.yaml @@ -3,7 +3,7 @@ all_resources: "*" all_s3_buckets: "arn:aws:s3:::*" all_rds_db_instances: "arn:aws:rds:*:*:db:*" -tag_list_backup_or_prod: # Resources tagged {"backup": "true"} OR {"env": "prod"} +tag_list_backup_or_prod: # Resources tagged {"backup": "true"} OR {"env": "prod"} - condition_type: "STRINGEQUALS" condition_key: "backup" condition_value: "true" @@ -11,7 +11,7 @@ tag_list_backup_or_prod: # Resources tagged {"backup": "true"} OR {"env": "prod" condition_key: "env" condition_value: "prod" -conditions_tagged_backup_and_prod: # Resources tagged {"backup": "true"} AND {"env": "prod"} +conditions_tagged_backup_and_prod: # Resources tagged {"backup": "true"} AND {"env": "prod"} string_equals: - condition_key: "aws:ResourceTag/backup" condition_value: "true" From 6e135594c84e7ec38fee802293cfed2befa613fa Mon Sep 17 00:00:00 2001 From: Helen Bailey Date: Wed, 5 Jul 2023 10:27:34 -0400 Subject: [PATCH 10/11] Update docs --- README.md | 2 ++ roles/backup_select_resources/README.md | 24 +++++++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2cac6b5b..6e7dc411 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,8 @@ Name | Description [cloud.aws_ops.aws_setup_credentials](https://github.com/ansible-collections/cloud.aws_ops/blob/main/roles/aws_setup_credentials/README.md)|A role to define credentials for aws modules. [cloud.aws_ops.awsconfig_detach_and_delete_internet_gateway](https://github.com/ansible-collections/cloud.aws_ops/blob/main/roles/awsconfig_detach_and_delete_internet_gateway/README.md)|A role to detach and delete the internet gateway you specify from virtual private cloud. [cloud.aws_ops.awsconfig_multiregion_cloudtrail](https://github.com/ansible-collections/cloud.aws_ops/blob/main/roles/awsconfig_multiregion_cloudtrail/README.md)|A role to create/delete a Trail for multiple regions. +[cloud.backup_create_plan](https://github.com/ansible-collections/cloud.aws_ops/blob/main/roles/backup_create_plan/README.md)|A role to create an AWS backup plan. +[cloud.backup_select_resources](https://github.com/ansible-collections/cloud.aws_ops/blob/main/roles/backup_create_plan/README.md)|A role to select resources to back up with an existing backup plan. [cloud.aws_ops.customized_ami](https://github.com/ansible-collections/cloud.aws_ops/blob/main/roles/customized_ami/README.md)|A role to manage custom AMIs on AWS. [cloud.aws_ops.ec2_instance_terminate_by_tag](https://github.com/ansible-collections/cloud.aws_ops/blob/main/roles/ec2_instance_terminate_by_tag/README.md)|A role to terminate the EC2 instances based on a specific tag you specify. [cloud.aws_ops.enable_cloudtrail_encryption_with_kms](https://github.com/ansible-collections/cloud.aws_ops/blob/main/roles/enable_cloudtrail_encryption_with_kms/README.md)|A role to encrypt an AWS CloudTrail trail using the AWS Key Management Service (AWS KMS) customer managed key you specify. diff --git a/roles/backup_select_resources/README.md b/roles/backup_select_resources/README.md index d4f9bb62..0fe73045 100644 --- a/roles/backup_select_resources/README.md +++ b/roles/backup_select_resources/README.md @@ -1,7 +1,7 @@ backup_select_resources ================== -A role to configure backups for selected resources. The role requires an existing backup vault and plan, and adds selected resources to the provided plan. A set of variables for resource selections is included for use as-is or as examples for modification. This role can be combined with the backup_plan_create role to create or update a backup plan if one does not already exist. +A role to configure backups for selected resources. The role requires an existing backup vault and plan, and adds selected resources to the provided plan. A set of variables for resource selections is included for use as-is or as examples for modification. This role can be combined with the `backup_create_plan` role to create or update a backup plan if one does not already exist. (see [example playbook](#create-backup-plan-and-select-resources)). Requirements ------------ @@ -40,14 +40,32 @@ Dependencies * role: [aws_setup_credentials](../aws_setup_credentials/README.md) -Example Playbook +Example Playbooks ---------------- +### Select resources - hosts: localhost roles: - role: cloud.aws_ops.backup_select_resources vars: - plan_name: daily-backup + plan_name: my-backup-plan + selection_name: s3_buckets + selection_resources: + - "{{ all_s3_buckets }}" + +### Create backup plan and select resources + + - hosts: localhost + roles: + - role: cloud.aws_ops.backup_create_plan + plan_name: my-backup-plan + plan_rules: "{{ daily_backup }}" + + - hosts: localhost + roles: + - role: cloud.aws_ops.backup_select_resources + vars: + plan_name: my-backup-plan selection_name: s3_buckets selection_resources: - "{{ all_s3_buckets }}" From 1cb6fda997efe6a96b19fa36a3b1d3f06fcd52c8 Mon Sep 17 00:00:00 2001 From: Helen Bailey Date: Mon, 10 Jul 2023 12:13:14 -0400 Subject: [PATCH 11/11] Ansible-lint fixes --- roles/backup_create_plan/tasks/main.yaml | 14 ++++++------- roles/backup_select_resources/tasks/main.yaml | 20 +++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/roles/backup_create_plan/tasks/main.yaml b/roles/backup_create_plan/tasks/main.yaml index f94fa28e..d2da44c2 100644 --- a/roles/backup_create_plan/tasks/main.yaml +++ b/roles/backup_create_plan/tasks/main.yaml @@ -3,7 +3,7 @@ block: - name: Fail when plan variables are not defined ansible.builtin.fail: - msg: "Required variable {{item}} has not been defined" + msg: "Required variable {{ item }} has not been defined" when: vars[item] is undefined loop: - plan_name @@ -21,17 +21,17 @@ backup_vault_name: "{{ vault_name }}" encryption_key_arn: "{{ vault_encryption_key_arn | default(omit) }}" tags: "{{ vault_tags | default(omit) }}" - register: backup_vault_result + register: backup_create_plan_backup_vault_result - name: Verify that vault has been created/updated ansible.builtin.debug: msg: Vault '{{ vault_name }}' successfully created/updated. - when: backup_vault_result is changed + when: backup_create_plan_backup_vault_result is changed - name: Verify that vault already exists ansible.builtin.debug: msg: Vault '{{ vault_name }}' exists, no updates needed. - when: backup_vault_result is not changed + when: backup_create_plan_backup_vault_result is not changed - name: Create or update backup plan amazon.aws.backup_plan: @@ -40,14 +40,14 @@ rules: "{{ plan_rules }}" advanced_backup_settings: "{{ plan_windows_vss_settings | default(omit) }}" tags: "{{ plan_tags | default(omit) }}" - register: backup_plan_result + register: backup_create_plan_backup_plan_result - name: Verify that plan has been created/updated ansible.builtin.debug: msg: Plan '{{ plan_name }}' successfully created/updated. - when: backup_plan_result is changed + when: backup_create_plan_backup_plan_result is changed - name: Verify that plan already exists ansible.builtin.debug: msg: Plan '{{ plan_name }}' exists, no updates needed. - when: backup_plan_result is not changed + when: backup_create_plan_backup_plan_result is not changed diff --git a/roles/backup_select_resources/tasks/main.yaml b/roles/backup_select_resources/tasks/main.yaml index 79d91227..d263b4df 100644 --- a/roles/backup_select_resources/tasks/main.yaml +++ b/roles/backup_select_resources/tasks/main.yaml @@ -17,22 +17,22 @@ amazon.aws.backup_plan_info: backup_plan_names: - "{{ plan_name }}" - register: backup_plan_info + register: backup_select_resources_backup_plan_info - name: Fail when backup plan does not exist ansible.builtin.fail: msg: Backup plan {{ plan_name }} does not exist, please create or confirm plan name is correct. - when: backup_plan_info.backup_plans | length == 0 + when: backup_select_resources_backup_plan_info.backup_plans | length == 0 - name: Get provided IAM role info community.aws.iam_role_info: name: "{{ backup_role_name }}" - register: role_info + register: backup_select_resources_role_info - name: Create new role when IAM role does not exist block: - name: Create role - when: role_info.iam_roles | length == 0 + when: backup_select_resources_role_info.iam_roles | length == 0 community.aws.iam_role: name: "{{ backup_role_name }}" state: present @@ -42,7 +42,7 @@ managed_policy: - arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForBackup wait: true - register: new_role_info + register: backup_select_resources_new_role_info - name: Wait for role to be created ansible.builtin.pause: @@ -50,26 +50,26 @@ - name: Set backup role ARN ansible.builtin.set_fact: - backup_role_arn: "{{ role_info.iam_roles[0].arn if new_role_info is skipped else new_role_info.arn }}" + backup_select_resources_backup_role_arn: "{{ backup_select_resources_role_info.iam_roles[0].arn if backup_select_resources_new_role_info is skipped else backup_select_resources_new_role_info.arn }}" - name: Create or update backup selection amazon.aws.backup_selection: state: present backup_plan_name: "{{ plan_name }}" selection_name: "{{ selection_name }}" - iam_role_arn: "{{ backup_role_arn }}" + iam_role_arn: "{{ backup_select_resources_backup_role_arn }}" resources: "{{ selection_resources }}" list_of_tags: "{{ selection_tags | default(omit) }}" not_resources: "{{ selection_excluded_resources | default(omit) }}" conditions: "{{ selection_conditions | default(omit) }}" - register: selection_result + register: backup_select_resources_selection_result - name: Verify that selection has been created/updated ansible.builtin.debug: msg: Backup selection '{{ selection_name }}' successfully created/updated. - when: selection_result is changed + when: backup_select_resources_selection_result is changed - name: Verify that selection already exists ansible.builtin.debug: msg: Backup selection '{{ selection_name }}' exists, no updates needed. - when: selection_result is not changed + when: backup_select_resources_selection_result is not changed