このブログでは、最初のAnsibleモジュールを作成する方法を紹介します。
もちろん、Ansible.comにはドキュメントがありますが、それを理解するのは困難です。この紹介に基づいて最初のモジュールを開始することは、非常に困難でした。そのため、このウォークスルーを作成しました。新規ユーザーは、より良い出発点に値します。
このブログは、次のトピックをカバーしています。
- Ansibleモジュールとは
- ビルド環境のセットアップ
- サーバーAPI
- モジュール自体の開発
Ansibleモジュールとは
Ansibleに精通している場合は、Ansibleで実行するすべてのタスクがAnsibleモジュールであることをおそらくご存知でしょう。そうでなければ、今あなたはそれを知っています。
, Ansible:
- name: python-requests yum: name: python-requests state: latest
Ansible yum
.
. .
- , . , , - Ansible Galaxy, Ansible.
Ansible, API . , , , , , , .
Ansible, .
VSCode Ansible. - , , , -.
, Ansible API, .
API . — . .
, VSCode.
git clone https://gitlab.com/techforce1/ansible-module.git -b blog-setup
, blog-setup!
3 (.devcontainer
, ansible
, api-server
). API. cmd
, api-server
docker build -t api-server
( ).
. docker run -it -d -p 5000: 5000 api-server
. API-. http://localhost:5000, -.
, , Ansible, — VSCode. .devcontainer. VSCode , devcontainer
.
devcontainer
VSCode devcontainer
.
, , devcontainer
. Ansible devcontainer
. , Ansible , VSCode.
VSCode , , Reopen in container
.
.
API
API API, . * http://localhost:5000/. - , . API, http://localhost:5000/API/users.
, « », , API . , http://localhost:5000/API/get-token. . admin
initial_password
.
, , API
API , - , , - .
API curl
. curl, :
$ curl -u admin:initial_password http:/172.17.0.1:5000/API/get-token { "duration": 600, "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjA1NzE0NjI5Ljk1NzU4ODd9.8yDkOzN0umO2hN_D84KLV4Q4OuWzQoNf8puXWku9F14" }
URL . , VSCode. , , IP- , API. .
, API, curl
:
$ curl -H 'Accept: application/json' -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjA1NzE0NjI5Ljk1NzU4ODd9.8yDkOzN0umO2hN_D84KLV4Q4OuWzQoNf8puXWku9F14" http:/172.17.0.1:5000/API/users { "Users": [ { "admin": true, "created": "Wed, 18 Nov 2020 14:41:31 GMT", "email": "admin@api.local", "id": 1, "username": "admin" } ] }
, API, GET
POST
:
{ "Users": [ { "username": "test", "email": "test@api.local", "password": "password", "admin": true } ] }
Ansible
. ansible/tasks/main.yml
. :
name: Add test user to API our_api_module: name: test1 state: present email: test1@test.local admin: False
— our_api_module
, 4 . . , Ansible.
. , , playbook. , Ansible , .
. 44, , , Ansible . arguments_spec
, playbook. false. , Ansible.
def main(): module = AnsibleModule( argument_spec=dict( state=dict(type='str', default='present', choices=['absent', 'present']), name=dict(type='str', required=True), email=dict(type='str', required=True), admin=dict(type='bool', default=False), base_url=dict(requred=False, default=None), username=dict(requred=False, default=None), password=dict(requred=False, default=None, no_log=True), ), supports_check_mode=False, )
59 ApiModule
, , 23. init. API. , , getToken
37.
urls
Ansible 3 .
def getToken(self): url = "{baseUrl}/API/get-token".format(baseUrl=self.baseUrl) response = open_url(url, method="GET", url_username=self.username, url_password=self.password, validate_certs=self.verifySsl) return json.loads(response.read())['token']
. , . 69. , . 2 : , (state). , if
, :
if api.state == 'absent': if api.user_exist(api.name): # do something to delete user elif api.state == 'present': if not api.user_exist(api.name): # do something to add user
. user_exist. ApiModule
:
def user_exist(self, name): url = "{baseUrl}/API/users".format(baseUrl=self.baseUrl) headers = { 'Accept': "application/json", "Authorization": "Bearer {}" . format(self.token), } response = open_url(url, method="GET", headers=headers, validate_certs=self.verifySsl) results = json.loads(response.read()) for user in results['Users']: if name == user['username']: return True return False
, , , . api endpoint /API/users , . True, False.
, , .
:
def user_add(self): url = "{baseUrl}/API/users".format(baseUrl=self.baseUrl) headers = { 'Accept': "application/json", 'Content-Type': "application/json", "Authorization": "Bearer {}" . format(self.token), } data = { 'username': self.name, 'email': self.email, 'admin': self.admin, 'password': self.password } json_data = json.dumps(data, ensure_ascii=False) try: open_url(url, method="POST", headers=headers, data=json_data, validate_certs=self.verifySsl) return True except: return False
. user_add . : HTTP
POST
DELETE
, , URL-.
, URL- :
url = "{baseUrl}/API/users/{username}".format(baseUrl=self.baseUrl, username=self.name)
if.
, playbook (tasks/main.yml
) :
- name: Add test2 user to API our_api_module: name: test2 state: present email: test2@test.local admin: False password: "test2test2" - name: Delete test1 user to API our_api_module: name: test1 state: absent email: test1@test.local admin: False password: "test3test3"
playbook, , 2 , 1 , .
おめでとう!これで、機能するAnsibleモジュールができました。ユーザー変更機能を追加してみましたか?また、実際のモジュールでエラー処理を行っているかのように、このモジュールにエラー処理を追加して、エラーを処理し、Ansibleに正しく返すことを検討してください。
それほど難しいことではありませんよね?本当じゃない。単純なPythonコードが不可欠です。
完全な最終結果を確認したい場合は、ブランチ結果のブログをご覧ください。