Skip to content

Instantly share code, notes, and snippets.

@elleryq
Last active June 13, 2023 13:24
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save elleryq/9c70e08b1b2cecc636d6 to your computer and use it in GitHub Desktop.
Save elleryq/9c70e08b1b2cecc636d6 to your computer and use it in GitHub Desktop.
Create Django super user in ansible
#!/usr/bin/expect
set timeout -1;
spawn {{django_dir}}/venv/bin/python manage.py changepassword {{admin_user}};
expect {
"Password:" { exp_send "{{admin_pass}}\r" ; exp_continue }
"Password (again):" { exp_send "{{admin_pass}}\r" ; exp_continue }
eof
}
---
# other tasks ...
- name: super user existed?
command: echo "from django.contrib.auth import get_user_model; User = get_user_model(); print(User.objects.filter(username='{{fota_admin_user}}').count()>0)" | {{ django_dir }}/venv/bin/python ./manage.py shell
args:
chdir: "{{django_dir}}"
environment:
DJANGO_SETTINGS_MODULE: "{{settings}}"
register: superuser_existed
- name: Create super user
django_manage: command="createsuperuser --noinput --username={{admin_user}} --email={{admin_email}}"
app_path={{django_dir}}
virtualenv={{django_dir}}/venv
settings={{settings}}
when: not superuser_existed
- name: Change password tricks
template: src=changepassword.sh.j2 dest={{django_dir}}/changepassword.sh mode=0755
- name: Change password
command: "{{django_dir}}/changepassword.sh"
args:
chdir: "{{django_dir}}"
environment:
DJANGO_SETTINGS_MODULE: "{{settings}}"
- name: remove changepassword.sh
file: path="{{django_dir}}/changepassword.sh" state=absent
django_dir: /webapp/djangoapp
settings: djangoapp.settings
admin_user: admin
admin_email: admin@example.com
admin_pass: PLEASE_MODIFY_ME
@ChaitDevOps
Copy link

Hi,
Thank you for this incredible workaround. what should the value of {{fota_admin_user}} ?. Is it same as admin_user ?

@secfigo
Copy link

secfigo commented Jul 4, 2017

Looks like a typo, you can safely replace it with {{admin_user}}

@AjinkyaBapat
Copy link

AjinkyaBapat commented Dec 27, 2017

This is not working for me.

`

  • name: Change password trick
    template: src=files/changepassword.sh.j2 dest={{path}}/changepassword.sh mode=0755
  • name: Change password
    command: "{{path}}/changepassword.sh"
    args:
    chdir: "{{path}}"

`

Returns

fatal: [default]: FAILED! => { "changed": false, "cmd": "/path/changepassword.sh", "failed": true, "invocation": { "module_args": { "_raw_params": "/path/changepassword.sh", "_uses_shell": false, "chdir": "/path", "creates": null, "executable": null, "removes": null, "warn": true } }, "msg": "[Errno 2] No such file or directory", "rc": 2 }

Script File exists on the mentioned path.

@Nadeflore
Copy link

Nadeflore commented Jun 9, 2018

I solved this issue by creating the user from django shell like this:

- name: Create default user                                                                       
  django_manage:                                                                                  
    command: shell -c "from django.contrib.auth import get_user_model; User=get_user_model(); User.objects.count()==0 or exit(); user=User.objects.create_user('{{ django_default_user_name }}', password='{{ django_default_user_password }}'); user.is_superuser=True; user.is_staff=True;user.save()"                                                                                                
    app_path: "{{ django_path }}"                                                                 
    virtualenv: "{{ virtualenv_path }}"                                                           

Is there any disadvantage to this method vs using createsuperuser command ?

@jonathanmorgan
Copy link

I ended up with this:

# check if superuser user exists, if not, create user.
- name: Check if superuser user exists, if not, create user.
  django_manage:
    command: shell -c "from django.contrib.auth import get_user_model; MyUser = get_user_model(); MyUser.objects.filter( username__exact = '{{ django_superuser_username }}' ).count() == 0 or exit(); new_super_user = MyUser( username = '{{ django_superuser_username }}', password='{{ django_superuser_password }}', email='{{ django_superuser_email }}', is_superuser = True, is_staff = True ); new_super_user.save();"
    app_path: "{{ django_project_folder_path }}"
    virtualenv: "{{ django_virtualenv_path }}"

And it worked, where the following did not (it never returned False that the user did not exist, so never created the user).

# check if superuser user exists.
- name: super user {{ django_superuser_username }} exists?
  command: echo "from django.contrib.auth import get_user_model; User = get_user_model(); print(User.objects.filter(username='{{ django_superuser_username }}').count()>0)" | {{ django_virtualenv_bin_path }}/python ./manage.py shell -i python
  args:
    chdir: "{{ django_project_folder_path }}"
  environment:
    DJANGO_SETTINGS_MODULE: "{{ django_settings_import }}"
  register: superuser_existed

# if no super user, create.
- name: If no super user {{ django_superuser_username }}, create super user
  django_manage:
    command: "createsuperuser --noinput --username={{ django_superuser_username }} --email={{ admin_email }}"
    app_path: "{{ django_project_folder_path }}"
    virtualenv: "{{ django_virtualenv_path }}"
    settings: "{{ django_settings_import }}"
  when: not superuser_existed

I left in the change of password, so it would update even if user already existed.

I probably did something wrong, but I prefer the shell command approach, anyway, since it keeps all the logic together, doesn't depend on the output of "manage.py shell", which I think could change depending on ipython, bpython, or python.

@seancook
Copy link

seancook commented Aug 7, 2018

Slight modification to @jonathanmorgan's approach that worked for me:

  django_manage:
    command: shell -c "from django.contrib.auth.hashers import make_password; from django.contrib.auth import get_user_model; MyUser = get_user_model(); MyUser.objects.filter( username__exact = '{{ admin_user }}' ).count() == 0 or exit(); new_super_user = MyUser( username = '{{ admin_user }}', email='{{ admin_email }}', is_superuser = True, is_staff = True ); new_super_user.password = make_password('{{ admin_pass }}'); new_super_user.save();"
    app_path: "{{ project_path }}"
    virtualenv: "{{ virtualenv_path }}"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment