From 60fb9fc208adebdc10c8a0f5ff1b3d61f8d6516d Mon Sep 17 00:00:00 2001 From: Will Thames Date: Fri, 5 Jul 2019 05:25:19 +1000 Subject: [PATCH] Fix EC2 test suite to work with testing policies (#44387) * Update testing policies to ensure all required permissions are present * Tidy up security policies to reduce duplicate permissions * Make roles static so that they can be present before CI is run, meaning that role creation permission is not required by the CI itself, only by someone setting up the roles prior to testing * Move contents to cloudfront policy to network policy to ensure policy count (maximum of 10) stays low * Maintain compute policy below 6144 bytes --- hacking/aws_config/setup-iam.yml | 1 + .../testing_policies/cloudfront-policy.json | 29 ------------ .../testing_policies/compute-policy.json | 16 +++---- .../testing_policies/container-policy.json | 1 + .../testing_policies/database-policy.json | 11 +++++ .../testing_policies/iam-policy.json | 17 ------- .../testing_policies/network-policy.json | 24 ++++++++++ .../testing_policies/security-policy.json | 41 +++------------- .../targets/ec2_instance/meta/main.yml | 1 + .../ec2_instance/playbooks/full_test.yml | 6 --- .../ec2_instance/playbooks/version_fail.yml | 47 ------------------- .../integration/targets/ec2_instance/runme.sh | 15 ------ .../targets/ec2_instance/tasks/main.yml | 37 +++++++++++++++ .../ec2_instance/tasks/version_fail.yml | 36 ++++++++++++++ 14 files changed, 125 insertions(+), 157 deletions(-) delete mode 100644 hacking/aws_config/testing_policies/cloudfront-policy.json delete mode 100644 hacking/aws_config/testing_policies/iam-policy.json delete mode 100644 test/integration/targets/ec2_instance/playbooks/full_test.yml delete mode 100644 test/integration/targets/ec2_instance/playbooks/version_fail.yml delete mode 100755 test/integration/targets/ec2_instance/runme.sh create mode 100644 test/integration/targets/ec2_instance/tasks/version_fail.yml diff --git a/hacking/aws_config/setup-iam.yml b/hacking/aws_config/setup-iam.yml index 27401429593..9dfaca53c97 100644 --- a/hacking/aws_config/setup-iam.yml +++ b/hacking/aws_config/setup-iam.yml @@ -52,3 +52,4 @@ state: present managed_policy: "{{ iam_managed_policies | json_query('results[].policy.policy_name') }}" profile: "{{ profile|default(omit) }}" + purge_policy: yes diff --git a/hacking/aws_config/testing_policies/cloudfront-policy.json b/hacking/aws_config/testing_policies/cloudfront-policy.json deleted file mode 100644 index 057cb586d6d..00000000000 --- a/hacking/aws_config/testing_policies/cloudfront-policy.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "AllowCloudfrontUsage", - "Effect": "Allow", - "Action": [ - "cloudfront:CreateDistribution", - "cloudfront:CreateDistributionWithTags", - "cloudfront:CreateCloudFrontOriginAccessIdentity", - "cloudfront:DeleteDistribution", - "cloudfront:GetDistribution", - "cloudfront:GetStreamingDistribution", - "cloudfront:GetDistributionConfig", - "cloudfront:GetStreamingDistributionConfig", - "cloudfront:GetInvalidation", - "cloudfront:ListDistributions", - "cloudfront:ListDistributionsByWebACLId", - "cloudfront:ListInvalidations", - "cloudfront:ListStreamingDistributions", - "cloudfront:ListTagsForResource", - "cloudfront:TagResource", - "cloudfront:UntagResource", - "cloudfront:UpdateDistribution" - ], - "Resource": "*" - } - ] -} diff --git a/hacking/aws_config/testing_policies/compute-policy.json b/hacking/aws_config/testing_policies/compute-policy.json index 123843b3dd8..a17850a4d08 100644 --- a/hacking/aws_config/testing_policies/compute-policy.json +++ b/hacking/aws_config/testing_policies/compute-policy.json @@ -43,6 +43,7 @@ "ec2:AssociateSubnetCidrBlock", "ec2:AttachInternetGateway", "ec2:AttachNetworkInterface", + "ec2:AttachVolume", "ec2:AttachVpnGateway", "ec2:CreateCustomerGateway", "ec2:CreateDhcpOptions", @@ -50,6 +51,7 @@ "ec2:CreateInternetGateway", "ec2:CreateKeyPair", "ec2:CreateNatGateway", + "ec2:CreateNetworkInterface", "ec2:CreateRoute", "ec2:CreateRouteTable", "ec2:CreateSecurityGroup", @@ -64,6 +66,7 @@ "ec2:DeleteInternetGateway", "ec2:DeleteKeyPair", "ec2:DeleteNatGateway", + "ec2:DeleteNetworkInterface", "ec2:DeleteRoute", "ec2:DeleteRouteTable", "ec2:DeleteSnapshot", @@ -87,6 +90,7 @@ "ec2:RegisterImage", "ec2:ReleaseAddress", "ec2:ReplaceRouteTableAssociation", + "ec2:ReplaceIamInstanceProfileAssociation", "ec2:ReportInstanceStatus" ], "Resource": "*" @@ -135,10 +139,7 @@ "elasticloadbalancing:DeleteTargetGroup", "elasticloadbalancing:DeregisterInstancesFromLoadBalancer", "elasticloadbalancing:DescribeInstanceHealth", - "elasticloadbalancing:DescribeLoadBalancerAttributes", - "elasticloadbalancing:DescribeLoadBalancerPolicies", - "elasticloadbalancing:DescribeLoadBalancerPolicyTypes", - "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeLoadBalancer*", "elasticloadbalancing:DescribeTags", "elasticloadbalancing:DisableAvailabilityZonesForLoadBalancer", "elasticloadbalancing:EnableAvailabilityZonesForLoadBalancer", @@ -177,9 +178,7 @@ "lambda:CreateEventSourceMapping", "lambda:GetAccountSettings", "lambda:GetEventSourceMapping", - "lambda:ListEventSourceMappings", - "lambda:ListFunctions", - "lambda:ListTags", + "lambda:List*", "lambda:TagResource", "lambda:UntagResource" ], @@ -199,8 +198,6 @@ "lambda:GetFunctionConfiguration", "lambda:GetPolicy", "lambda:InvokeFunction", - "lambda:ListAliases", - "lambda:ListVersionsByFunction", "lambda:PublishVersion", "lambda:RemovePermission", "lambda:UpdateAlias", @@ -219,6 +216,7 @@ "Resource": [ "arn:aws:iam::{{aws_account}}:role/ansible_lambda_role", "arn:aws:iam::{{aws_account}}:role/ecsInstanceRole", + "arn:aws:iam::{{aws_account}}:role/ec2InstanceRole", "arn:aws:iam::{{aws_account}}:role/ecsServiceRole", "arn:aws:iam::{{aws_account}}:role/aws_eks_cluster_role", "arn:aws:iam::{{aws_account}}:role/ecsTaskExecutionRole" diff --git a/hacking/aws_config/testing_policies/container-policy.json b/hacking/aws_config/testing_policies/container-policy.json index d14deacf846..1a6641f36b7 100644 --- a/hacking/aws_config/testing_policies/container-policy.json +++ b/hacking/aws_config/testing_policies/container-policy.json @@ -46,6 +46,7 @@ "ecs:StopTask", "ecs:UpdateService", "elasticloadbalancing:Describe*", + "iam:GetInstanceProfile", "iam:GetPolicy", "iam:GetPolicyVersion", "iam:GetRole", diff --git a/hacking/aws_config/testing_policies/database-policy.json b/hacking/aws_config/testing_policies/database-policy.json index 472e6206c0c..f4c824ae21d 100644 --- a/hacking/aws_config/testing_policies/database-policy.json +++ b/hacking/aws_config/testing_policies/database-policy.json @@ -86,6 +86,17 @@ ], "Effect": "Allow", "Resource": "*" + }, + { + "Sid": "DMSEndpoints", + "Effect": "Allow", + "Action": [ + "dms:CreateEndpoint", + "dms:DeleteEndpoint", + "dms:DescribeEndpoints", + "dms:ModifyEndpoint" + ], + "Resource": ["*"] } ] } diff --git a/hacking/aws_config/testing_policies/iam-policy.json b/hacking/aws_config/testing_policies/iam-policy.json deleted file mode 100644 index 6105e40a92e..00000000000 --- a/hacking/aws_config/testing_policies/iam-policy.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "AllowAccessToServerCertificates", - "Effect": "Allow", - "Action": [ - "iam:ListServerCertificates", - "iam:UploadServerCertificate", - "iam:UpdateServerCertificate", - "iam:DeleteServerCertificate", - "iam:GetServerCertificate" - ], - "Resource": "*" - } - ] -} diff --git a/hacking/aws_config/testing_policies/network-policy.json b/hacking/aws_config/testing_policies/network-policy.json index d28115ee459..d5cb2d36ec9 100644 --- a/hacking/aws_config/testing_policies/network-policy.json +++ b/hacking/aws_config/testing_policies/network-policy.json @@ -22,6 +22,30 @@ "ec2:DescribeTransitGateways" ], "Resource": "*" + }, + { + "Sid": "AllowCloudfrontUsage", + "Effect": "Allow", + "Action": [ + "cloudfront:CreateDistribution", + "cloudfront:CreateDistributionWithTags", + "cloudfront:CreateCloudFrontOriginAccessIdentity", + "cloudfront:DeleteDistribution", + "cloudfront:GetDistribution", + "cloudfront:GetStreamingDistribution", + "cloudfront:GetDistributionConfig", + "cloudfront:GetStreamingDistributionConfig", + "cloudfront:GetInvalidation", + "cloudfront:ListDistributions", + "cloudfront:ListDistributionsByWebACLId", + "cloudfront:ListInvalidations", + "cloudfront:ListStreamingDistributions", + "cloudfront:ListTagsForResource", + "cloudfront:TagResource", + "cloudfront:UntagResource", + "cloudfront:UpdateDistribution" + ], + "Resource": "*" } ] } diff --git a/hacking/aws_config/testing_policies/security-policy.json b/hacking/aws_config/testing_policies/security-policy.json index 2cb253bf4a7..4b1f53e3628 100644 --- a/hacking/aws_config/testing_policies/security-policy.json +++ b/hacking/aws_config/testing_policies/security-policy.json @@ -33,7 +33,9 @@ "iam:CreateRole", "iam:DeleteRole", "iam:DetachRolePolicy", - "iam:PassRole" + "iam:PassRole", + "iam:UpdateAssumeRolePolicy", + "sts:AssumeRole" ], "Resource": "arn:aws:iam::{{ aws_account }}:role/ansible-test-*", "Effect": "Allow", @@ -91,22 +93,6 @@ "arn:aws:logs:{{aws_region}}:{{aws_account}}:log-group:ansible-testing*" ] }, - { - "Sid": "AllowSTSAnsibleTests", - "Action": [ - "iam:CreateRole", - "iam:DeleteRole", - "iam:DetachRolePolicy", - "sts:AssumeRole", - "iam:AttachRolePolicy", - "iam:CreateInstanceProfile" - ], - "Effect": "Allow", - "Resource": [ - "arn:aws:iam::{{aws_account}}:role/ansible-test-sts-*", - "arn:aws:iam::{{aws_account}}:instance-profile/ansible-test-sts-*" - ] - }, { "Sid": "AllowAccessToUnspecifiedKMSResources", "Effect": "Allow", @@ -132,26 +118,13 @@ "Resource": "*" }, { - "Sid": "AllowAccessToSpecifiedIAMResources", + "Sid": "AllowAccessToServerCertificates", "Effect": "Allow", "Action": [ - "iam:CreateRole", - "iam:DeleteRole", - "iam:GetRole", - "iam:PassRole", - "iam:UpdateAssumeRolePolicy" - ], - "Resource": "arn:aws:iam::{{aws_account}}:role/ansible-test-*" - }, - { - "Sid": "AllowInstanceProfileCreation", - "Effect": "Allow", - "Action": [ - "iam:AddRoleToInstanceProfile", - "iam:CreateInstanceProfile", - "iam:RemoveRoleFromInstanceProfile" + "iam:ListServerCertificates", + "iam:UploadServerCertificate" ], - "Resource": "arn:aws:iam::{{aws_account}}:instance-profile/ansible-test-*" + "Resource": "*" } ] } diff --git a/test/integration/targets/ec2_instance/meta/main.yml b/test/integration/targets/ec2_instance/meta/main.yml index 1f64f1169a9..38b31be0728 100644 --- a/test/integration/targets/ec2_instance/meta/main.yml +++ b/test/integration/targets/ec2_instance/meta/main.yml @@ -1,3 +1,4 @@ dependencies: - prepare_tests - setup_ec2 + - setup_remote_tmp_dir diff --git a/test/integration/targets/ec2_instance/playbooks/full_test.yml b/test/integration/targets/ec2_instance/playbooks/full_test.yml deleted file mode 100644 index ca5606e6c88..00000000000 --- a/test/integration/targets/ec2_instance/playbooks/full_test.yml +++ /dev/null @@ -1,6 +0,0 @@ -- hosts: localhost - connection: local - environment: "{{ ansible_test.environment }}" - - roles: - - ec2_instance diff --git a/test/integration/targets/ec2_instance/playbooks/version_fail.yml b/test/integration/targets/ec2_instance/playbooks/version_fail.yml deleted file mode 100644 index 223d635ff36..00000000000 --- a/test/integration/targets/ec2_instance/playbooks/version_fail.yml +++ /dev/null @@ -1,47 +0,0 @@ -- hosts: localhost - connection: local - environment: "{{ ansible_test.environment }}" - vars: - resource_prefix: 'ansible-testing' - - tasks: - - block: - - name: set up aws connection info - set_fact: - aws_connection_info: &aws_connection_info - aws_access_key: "{{ aws_access_key }}" - aws_secret_key: "{{ aws_secret_key }}" - security_token: "{{ security_token }}" - region: "{{ aws_region }}" - no_log: True - - - name: Include vars file in {{ playbook_dir }}../defaults/main.yml - include_vars: - file: '{{ playbook_dir }}/../defaults/main.yml' - - - name: create t3.nano with cpu options (fails gracefully) - ec2_instance: - state: present - name: "ansible-test-{{ resource_prefix | regex_search('([0-9]+)$') }}-ec2" - image_id: "{{ ec2_ami_image[aws_region] }}" - instance_type: t3.nano - cpu_options: - core_count: 1 - threads_per_core: 1 - <<: *aws_connection_info - register: ec2_instance_cpu_options_creation - ignore_errors: yes - - - name: check that graceful error message is returned when creation with cpu_options and old botocore - assert: - that: - - ec2_instance_cpu_options_creation.failed - - 'ec2_instance_cpu_options_creation.msg == "cpu_options is only supported with botocore >= 1.10.16"' - - always: - - name: cleanup c4.large in case graceful failure was in fact a graceful success - ec2_instance: - state: absent - name: "ansible-test-{{ resource_prefix | regex_search('([0-9]+)$') }}-ec2" - <<: *aws_connection_info - ignore_errors: yes diff --git a/test/integration/targets/ec2_instance/runme.sh b/test/integration/targets/ec2_instance/runme.sh deleted file mode 100755 index 2d2dac49518..00000000000 --- a/test/integration/targets/ec2_instance/runme.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -set -eux - -export ANSIBLE_ROLES_PATH=../../targets/ - -# Test graceful failure for older versions of botocore -source virtualenv.sh -pip install 'botocore<1.10.16' 'boto3<1.7.16' -ansible-playbook -v playbooks/version_fail.yml "$@" - -# Run full test suite -source virtualenv.sh -pip install 'botocore>=1.10.16' boto3 -ansible-playbook -v playbooks/full_test.yml "$@" diff --git a/test/integration/targets/ec2_instance/tasks/main.yml b/test/integration/targets/ec2_instance/tasks/main.yml index 030966569e0..a7aec5e42ed 100644 --- a/test/integration/targets/ec2_instance/tasks/main.yml +++ b/test/integration/targets/ec2_instance/tasks/main.yml @@ -8,6 +8,43 @@ - block: + - set_fact: + virtualenv: "{{ remote_tmp_dir }}/virtualenv" + virtualenv_command: "{{ ansible_python_interpreter }} -m virtualenv" + + - set_fact: + virtualenv_interpreter: "{{ virtualenv }}/bin/python" + + - pip: + name: virtualenv + + - pip: + name: + - 'botocore<1.10.16' + - boto3 + - coverage + virtualenv: "{{ virtualenv }}" + virtualenv_command: "{{ virtualenv_command }}" + virtualenv_site_packages: no + + - include_tasks: version_fail.yml + vars: + ansible_python_interpreter: "{{ virtualenv_interpreter }}" + + - file: + path: "{{ virtualenv }}" + state: absent + + - pip: + name: + - 'botocore>=1.10.16' + - boto3 + - coverage + virtualenv: "{{ virtualenv }}" + virtualenv_command: "{{ virtualenv_command }}" + virtualenv_site_packages: no + + - include_tasks: env_setup.yml - include_tasks: cpu_options.yml - include_tasks: termination_protection.yml diff --git a/test/integration/targets/ec2_instance/tasks/version_fail.yml b/test/integration/targets/ec2_instance/tasks/version_fail.yml new file mode 100644 index 00000000000..a5bc1b31aa6 --- /dev/null +++ b/test/integration/targets/ec2_instance/tasks/version_fail.yml @@ -0,0 +1,36 @@ +- block: + - name: set up aws connection info + set_fact: + aws_connection_info: &aws_connection_info + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token }}" + region: "{{ aws_region }}" + no_log: True + + - name: create t3.nano with cpu options (fails gracefully) + ec2_instance: + state: present + name: "ansible-test-{{ resource_prefix | regex_search('([0-9]+)$') }}-ec2" + image_id: "{{ ec2_ami_image[aws_region] }}" + instance_type: t3.nano + cpu_options: + core_count: 1 + threads_per_core: 1 + <<: *aws_connection_info + register: ec2_instance_cpu_options_creation + ignore_errors: yes + + - name: check that graceful error message is returned when creation with cpu_options and old botocore + assert: + that: + - ec2_instance_cpu_options_creation.failed + - 'ec2_instance_cpu_options_creation.msg == "cpu_options is only supported with botocore >= 1.10.16"' + + always: + - name: cleanup t3.nano in case graceful failure was in fact a graceful success + ec2_instance: + state: absent + name: "ansible-test-{{ resource_prefix | regex_search('([0-9]+)$') }}-ec2" + <<: *aws_connection_info + ignore_errors: yes