DevOps/Ansible

Ansible - 4. Sonarqube 설치하기

Camouflage129 2020. 9. 7. 15:44

먼저 제가 설치한 방법에 대해서 전체 플로우를 설명해드리도록 하겠습니다.

 

소나큐브 7.2까지는 Java1.8로 가능하지만 이후에는 더 높은 자바버전이 필요합니다.

저는 Jenkins 서버등 Java1.8을 사용하고 있기 때문에 해당 버전을 사용하기로 하였으며,

따라서 variable.yaml에 해당 url을 적어놓고 다운받아 설치하였습니다.

 

소나큐브를 사용하기 위한 DB가 필요합니다.

하지만 많이 사용하지는 않기 때문에 로컬에 설치하여 구동하기로 했고, 따라서 mysql을 설치하는 코드도 같이 작성되어있습니다.

mysql을 처음 세팅하게 되면 임시 패스워드가 로그에 저장되게 되는데, 이를 따로 명령어로 뽑아 ansible의 변수로 사용해보려 했으나,

잘 되지 않아 python으로 해당 패스워드를 파일로 만들고 이를 읽어서 mysql 임시비밀번호를 변경하도록 구성하였습니다.

 

따라서 소나큐브를 세팅하는 sql과 임시 패스워드를 파일로 만들어주는 파일들을 s3에 저장하여서 가져오도록 하였습니다.

(Jenkins Server에 해당 버킷 Read권한 부여)

 

마지막으로  소나큐브를 서비스로 세팅하여 서버가 스케줄링 되더라도, 자동으로 시작할 수 있도록 구성하였습니다.

 

파일은 아래와 같습니다.

 

get_mysql_root_temp_passwd.py
0.00MB
sonar.sql
0.00MB

 

1. ansible.cfg

 

[defaults]
host_key_checking = False
command_warnings = False

 

2. Inventory.ini

 

[sonarqube:vars]
ansible_ssh_private_key_file=/var/lib/jenkins/key/abcd.pem
ansible_user=ec2-user

[sonarqube]
10.0.1.150

 

3. playbook.yaml

 

변수는 {{ 변수이름 }}과 같이 정의한 후 variable.yaml 파일에서 "변수이름: 값"의 형태로 선언하여 사용해주시면 됩니다.

또한 맨 윗부분에 자세히 보시면 include_vars: variable.yaml으로 참조하여 사용한다는 것을 알 수 있습니다.

적절하게 변경하여 활용해서 사용하시면 되겠습니다.

 

---
  - name: set sonarqube
    hosts: sonarqube
    become_user: root
    become: yes
    tasks:
      - include_vars: variable.yaml
      # 유저 생성
      - name: add user
        user:
          name: sonarqube
          password: "{{ sonar_user_password }}"
      
      # Admin 권한 부여
      - name: modify visudo
        lineinfile:
          path: /etc/sudoers
          insertafter: '^root*'
          state: present
          line: "sonarqube\tALL=(ALL)\tNOPASSWD:ALL"
          validate: 'visudo -cf %s'
      
      # 패스워드 기반 접속 허용
      - name: modify sshd_config
        replace:
          path: /etc/ssh/sshd_config
          regexp: 'PasswordAuthentication no'
          replace: 'PasswordAuthentication yes'
  
      # OS 단 위의 세팅 반영
      - name: restart sshd
        service:
          name: sshd
          state: restarted
  
      # 자바 설치
      - name: Install Open-JDK8
        yum:
          state: installed
          name: java-1.8.0-openjdk-devel.x86_64
      
      # Mysql 5.7 (특정버전) RPM 설치
      - name: Install Mysql RPM
        yum:
          state: installed
          name: "{{ mysql_rpm_url }}"
          
      # 위의 RPM으로 부터 패키지 설치
      - name: Install Mysql
        yum:
          state: installed
          name: 
            - mysql-community-client
            - mysql-server
      
      # Mysql Service 시작
      - name: Systemctl Mysql
        systemd:
          name: mysqld
          state: started
          enabled: yes
  
      # Check Root Password File
      - name: check installed sonarqube
        stat:
          path: "{{ sonarqube_path }}/mysql_root_temp_password"
        register: check_mysql_root_temp_password

      # Mysql 임시 비밀번호 파일로 생성해주는 Python 다운로드
      - name: Download get mysql temp pw python in S3
        command: aws s3 cp {{ sonar_s3_url }}/get_mysql_root_temp_passwd.py {{ sonarqube_path }}/get_mysql_root_temp_passwd.py
        when: check_mysql_root_temp_password.stat.exists == False

      # python file 권한 부여
      - name: add permission to python file
        file:
          path: "{{ sonarqube_path }}/get_mysql_root_temp_passwd.py"
          owner: sonarqube
          group: sonarqube
          mode: 0755
        when: check_mysql_root_temp_password.stat.exists == False
  
      # Mysql 임시 비밀번호 파일로 생성 (특수문자 앞에 \ 필요)
      - name: make temporary root pass to file
        command: python3 {{ sonarqube_path }}/get_mysql_root_temp_passwd.py
        when: check_mysql_root_temp_password.stat.exists == False
      
      # Check Root Password File
      - name: check installed sonarqube
        stat:
          path: "{{ sonarqube_path }}/mysql_root_temp_password"
        register: check_mysql_root_temp_password
  
      # Mysql 임시 비밀번호 변수 선언
      - name: Acquire temporary root pass
        shell: >
          cat {{ sonarqube_path }}/mysql_root_temp_password
        register: mysql_root_temp_password
        when: check_mysql_root_temp_password.stat.exists == False
  
      # DB 루트 유저 비번 변경
      - name: Update MySQL root password for localhost root account
        shell: >
          mysql -uroot -p{{ mysql_root_temp_password.stdout }} -e 'ALTER USER "root"@"localhost" IDENTIFIED WITH mysql_native_password BY "{{ mysql_root_passwd }}";' --connect-expired-password
        when: check_mysql_root_temp_password.stat.exists == False

      # Sql File Check
      - name: check sonar db set
        stat:
          path: "{{ sonarqube_path }}/sonar.sql"
        register: check_sonar_sql

      # Sonar DB Setting Sql
      - name: Download Sonar DB Sql
        command: aws s3 cp {{ sonar_s3_url }}/sonar.sql {{ sonarqube_path }}/sonar.sql
        when: check_sonar_sql.stat.exists == False

      # DB 세팅
      - name: set sonar DB
        shell: >
          mysql -uroot -p{{ mysql_root_passwd }} < {{ sonarqube_path }}/sonar.sql
        when: check_sonar_sql.stat.exists == False

      # 소나큐브 설치 되었는지 체크 (wget 형태이기 때문에 체크하지 않으면, 계속 수행 됨)
      - name: check installed sonarqube
        stat:
          path: "/opt/sonarqube"
        register: sonarqube
  
      # 소나큐브 다운로드
      - name: wget sonarqube
        get_url: 
          url: "{{ sonarqube_url }}"
          dest: /opt
        when: sonarqube.stat.exists == False
  
      # 압축 해제
      - name: unzip sonarqube
        unarchive: 
          src: /opt/sonarqube-7.2.zip
          dest: /opt
          copy: no
        when: sonarqube.stat.exists == False
      
      # 소나큐브 폴더 이름 변경
      - name: change dir name sonarqube
        command: mv /opt/sonarqube-7.2 /opt/sonarqube
        when: sonarqube.stat.exists == False
      
      # 소나큐브 권한 변경 (sonarqube 유저로 실행해야 됨)
      - name: change chown sonarqube
        shell: chown -R sonarqube:sonarqube /opt/sonarqube
        when: sonarqube.stat.exists == True
        args:
          warn: false
  
      # 소나큐브 실행 유저 세팅
      - name: set user in sonar.sh
        replace:
          path: /opt/sonarqube/bin/linux-x86-64/sonar.sh
          regexp: "#RUN_AS_USER="
          replace: "RUN_AS_USER=sonarqube"
        when: sonarqube.stat.exists == True
      
      # 소나큐브 DB Config 세팅
      - name: set Sonarqube Config
        replace:
          path: /opt/sonarqube/conf/sonar.properties
          regexp: "{{ item.regexp1 }}"
          replace: "{{ item.replace }}"
        with_items:
          - { regexp1: '#sonar.jdbc.username=', replace: 'sonar.jdbc.username={{ mysql_user_name }}' }
          - { regexp1: '#sonar.jdbc.password=', replace: 'sonar.jdbc.password={{ mysql_user_passwd }}' }
          - { regexp1: '#sonar.jdbc.url=jdbc:mysql:.*', replace: 'sonar.jdbc.url={{ mysql_jdbc_url }}' }
          - { regexp1: '#sonar.web.port=9000', replace: 'sonar.web.port={{ sonar_web_port }}' }
        when: sonarqube.stat.exists == True

      # 소나큐브 Systemctl 서비스 등록 여부 체크
      - name: check set sonarqube service
        stat:
          path: "/usr/lib/systemd/system/sonar.service"
        register: sonarqube_service
  
      # 소나큐브 서비스로 등록
      - name: add service sonarqube
        copy:
          dest: /usr/lib/systemd/system/sonar.service
          content: |
            [Unit]
            Description=SonarQube service
            After=syslog.target network.target

            [Service]
            Type=simple
            User=sonarqube
            Group=sonarqube
            PermissionsStartOnly=true
            ExecStart=/bin/nohup /usr/bin/java -Xms32m -Xmx32m -Djava.net.preferIPv4Stack=true -jar /opt/sonarqube/lib/sonar-application-7.2.jar
            StandardOutput=syslog
            LimitNOFILE=65536
            LimitNPROC=8192
            TimeoutStartSec=5
            Restart=always
            SuccessExitStatus=143

            [Install]
            WantedBy=multi-user.target
        when: sonarqube_service.stat.exists == False
      
      # 서버가 온 될때마다 수행될 수 있도록 Systemctl enable 설정
      - name: systemctl enable sonarqube
        systemd:
          daemon_reload: yes
          name: sonar.service
          state: started
          enabled: yes
        when: sonarqube_service.stat.exists == False

 

4. variable.yaml

 

비밀번호를 세팅 할때는 python의 passlib라는 라이브러리를 설치하여 사용해 주셔야 합니다.

 

python3 -m pip install -y passlib
python3 -c "from passlib.hash import sha512_crypt; import getpass; print(sha512_crypt.using(rounds=5000).hash(getpass.getpass()))"

 

아래와 같이 명령어가 끝나면 비밀번호를 입력하라고 할텐데,

이때 입력하는 비밀번호가 암호화된 값을 아래 variable.yaml에 넣어주시면 됩니다. (아무거나 막 입력한 경우)

 

 

---
sonar_user_password: $6$d6goXGIW236hX~~~~
mysql_root_passwd: Root123!@#

mysql_user_name: sonar
mysql_user_passwd: Sonar123!@#
mysql_jdbc_url: jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false

sonar_web_port: 9000
sonarqube_path: /opt/sonarqube

get_py_my_s3_url: s3://ansible-files/sonarqube/get_mysql_root_temp_passwd.py
mysql_rpm_url: https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm
sonarqube_url: https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-7.2.zip

 

 

이전 글에 있는 파이프라인에 stage를 추가하여 배포를 계속 테스트해 본 결과입니다.

 

 

이렇게 서버 환경세팅을 한번 세팅하고 CICD로 관리하게 되면,

 

다음에 다른 프로젝트 혹은 환경에 구축해야 할 경우에 고민없이 쉽게 구축하여 사용할 수 있습니다.

 

앤서블과 그 예시에 대해 간단하게 알아봤습니다.