2017-09-06 6 views
0

이 질문은 AWS가 아닌 Anecess에서 루핑하는 것에 관한 내용이지만 AWS 배포 문제를 예제로 사용하겠습니다.Angex에서 중첩 된 값을 정규 표현식으로 바꾸는 방법

배포 스크립트의 경우 Amazon EC2 컨테이너 서비스의 일부 클러스터를 반복하려고합니다. 궁극적으로 수행 할 작업은 클러스터에서 각 서비스를 다시 시작하는 것입니다. 이름이 주어지면 서비스를 다시 시작할 수 있습니다. 그러나 완전한 ARN이 아닌 단순한 이름이 필요합니다. 그래서 내가 클러스터 당 서비스를보고 같은 것을 얻을 :

results: 
- _ansible_item_result: true 
    _ansible_no_log: false 
    _ansible_parsed: true 
    ansible_facts: 
    services: 
    - arn:aws:ecs:eu-central-1:55:service/test-services 
    changed: false 
    failed: false 
    invocation: 
    module_args: 
     aws_access_key: null 
     aws_secret_key: null 
     cluster: services 
     details: false 
     ec2_url: null 
     profile: null 
     region: null 
     security_token: null 
     service: null 
     validate_certs: true 
    item: services 
- _ansible_item_result: true 
    _ansible_no_log: false 
    _ansible_parsed: true 
    ansible_facts: 
    services: 
    - arn:aws:ecs:eu-central-1:55:service/test-service 
    - arn:aws:ecs:eu-central-1:55:service/frontend 
    - arn:aws:ecs:eu-central-1:55:service/beats 
    changed: false 
    failed: false 
    invocation: 
    module_args: 
     aws_access_key: null 
     aws_secret_key: null 
     cluster: test-service 
     details: false 
     ec2_url: null 
     profile: null 
     region: null 
     security_token: null 
     service: null 
     validate_certs: true 
    item: test-service module_args: 
    aws_access_key: null 
    aws_secret_key: null 
    cluster: test-service 
    details: false 
    ec2_url: null 
    profile: null 
    region: null 
    security_token: null 
    service: null 
    validate_certs: true 

항목 : 시험 서비스

가 지금은 서비스의 짧은 이름으로 각각의 ARN을 대체 할을. 예 : arn:aws:ecs:eu-central-1:55:service/test-servicetest-service이됩니다.

가 교체 후 나는이 서비스를 통해 루프를 할 수있는 0에 원하는 수를 설정하여이를 해제 (후에 나는 다시 그들을 다시 켜집니다) :

- name: "Turn services off" 
    ecs_service: 
    name: "{{ item[1]}}" 
    desired_count: 0 
    task_definition: "{{ taskdefinitions[item[1]] }}" 
    cluster: "{{ item[0].item }}" 
    state: present 
with_subelements: 
    - "{{ result.results }}" 
    - ansible_facts.services 
register: turnOffServiceResult 

taskdefinitions 간단한 DICT의 I 인 경우 플레이 북에 정의 :

:

taskdefinitions: 
    services: 
    - test-services 
    test-xde-worker-service: 
    - test-service 

나는 다음을 수행하여 대체 정규식하려고 변수 result에 위의 AWS 목록을 가져 그래서 후3210

이 잘 작동하지만 분명히 한 클러스터의 서비스 이름을 바꿉니다 및 dict ansible_facts 다른 필드를 잃게됩니다. 후자는 수용 가능하고, 후자는 허용되지 않습니다. 여기에 질문이 있습니다. 중첩 목록의 텍스트를 어떻게 바꿀 수 있습니까? 또 다른 문제는 taskdefinitions에 포함되지 않은 서비스를 건너 뛰는 것을 건너 뛰는 것일 수 있지만 이는 당면한 문제가 아닙니다.

+0

왜 전체 DICT 내부 값을 대체하지? –

+0

좋은 지적, 변수를 전달할 때 필터를 사용하여 시도했지만 작동하지 않는 것 같습니다. task_define을 찾기 위해'item [1]'을 명명 된 인덱스로 사용한다는 것을 알게 될 것이다. 내가 거기에 필터를 적용 할 수있는 방법을 말해 줄 수 있다면, 나는 매우 행복해 질 것이다. 어떤 점에서는 누군가가 중첩 된 목록의 일부 값을 필터링해야 할 것이라고 확신합니다. 그러므로보다 일반적인 질문입니다. – titusn

답변

2

복잡한 개체의 임의 항목을 수정하는 기본 제공 방법은 알고 있지 않습니다 (적어도 현재 Ansible 2.3 이상).

원본 개체 (select, map(attribute=...), json_query 등)에서 필수 항목을 선택한 다음 해당 축소 세트/목록의 항목을 수정하십시오. 귀하의 가상의 예를 들어, result.results[].ansible_facts.services[] 같은 모든 클러스터와 모든 서비스를 선택하려면 map('regex_replace',...이 목록과 같은 JMESPath.

또는 복잡한 객체를 반복 예를 들어, 루프 내부에 수정을 적용`ecs_service`에 전달할 때

- name: "Turn services off" 
    ecs_service: 
    name: "{{ myname }}" 
    desired_count: 0 
    task_definition: "{{ taskdefinitions[myname] }}" 
    cluster: "{{ mycluster }}" 
    state: present 
    vars: 
    mycluster: "{{ item[0].item }}" 
    myname: "{{ item[1] | regex_search('[^/]*$') }}" 
    with_subelements: 
    - "{{ result.results }}" 
    - ansible_facts.services 
+0

그것은 유망한 소리가 난다, 나는 그것을 시험해보고, 여기에서 돌아올 것이다. – titusn

+0

예, vars를 사용하면 효과가있었습니다. 내 이전 시도도 작동했음을 알았지 만, UpdateService 작업을 호출 할 때 오류 (ClientException)가 발생했습니다. 패밀리에는 유효하지 않은 문자가 포함되어 있습니다. "분명히 나는 ​​멍청한 실수를 저질 렀고 목록을 반환했습니다. 단일 값 대신에. regex 개선에 좋은 하나. – titusn

+0

호기심에서 벗어난 이유는 무엇입니까? 내가 올바른 데이터를 제공하지 않은 이유는 무엇입니까? 나는 모든 것이 문제 였다고 생각한다. 단지 계좌 번호와 일부 서비스 이름을 익명으로 처리했다. – titusn