Wednesday, November 4, 2026

What's Next?

 

"Well, when the president does it … that means that it is not illegal."

Richard M. Nixon


On 3 November 2026, America rejected the authoritarian ideology brought to the people by the Republican party. The jubilation is immense. The victory made more sweet by the hopes of 2016 and 2024 being dashed, unexpectedly, carries with it a warning. Yesterdays effort, as important as it is, amounts just opening the front door of the Capitol. America is today, in as much jeopardy as we were two days ago. We will remain so, until we have dealt with the problems that brought us to this place. A failure to do so will simply leave America open to further erosion of democratic principles, ensuring this fight again and again, until at some inevitable point (because no one can keep winning forever), we lose and this experiment ends.

First and foremost, what we have right now is complete rejection of the law by our leaders. They are still in power, and there are countless statutes and traditions sitting idly by, awaiting molestation by the Republicans holding office over the next two months. We need to ensure this never happens again, and herein lies our first opportunity.

Our very first action is to sweep the halls for those who have engaged in corruption, or the violation of law. We then give them the fair trials that they would have denied others. And when those trials result in conviction, we incarcerate each and every one of those those for whom the district attorneys have proven beyond reasonable doubt, the elements of their crimes. We do this not for vengeance; the damage is done, and our time would be better spent cleaning up and securing democratic institutions. We do this to protect our grandchildren, and theirs, and the ones after that. This is our duty as citizens of a free society. We are compelled by by virtue, to demonstrate to any of those in the years ahead wishing to take control of government for their own aims, America will not tolerate authoritarianism. Further, restitution is expected. If you stole from the United States, you have a debt obligation and the Justice Department needs to start taking your money and restoring it to the people. This includes anyone at any level inside or outside the government who engaged in criminal behavior.

Why is this so critical? If one argues, ‘we’ve learned our lesson,’ then we need to stop thinking of ourselves. We must consider the future generations that were not here to see this in real time. They have learned nothing, yet, thus we must offer them a lesson to operate from when a charlatan like Trump comes along again.

As we are dealing with the corruption, and are able to hand that off to a lawful Justice Department post 2028, we need to move on to securing the democratic institutions - making them more resilient to attack. This will require significant disambiguation of the roles of the president, congresspersons, and federal justices. The Court argues the President cannot be investigated while in office. The people expect the phrase “no one is above the law” to be honored. This needs to be worked out such that there is clear guidance on what the president can and cannot do. Further, the Court has engaged in numerous power grabs with respect to both Congress and the presidency. This Court will be known well into the future as horribly partisan and viewed with disdain. It requires restructuring. The number of justices is irrelevant. What is relevant is sitting on cases where you have ties or a financial interest in one or both parties. We must have ethics reform in the court. Without it, the law is nothing more than what those in power say it is. When any branch of government attempts to contrive law or regulation taking power from the other branches, this should be subject approval by the other branches. After all, we’re all in this together, right?

Along the same lines, we need to create minimum standards at the federal level for fair elections. This is legal, but once the minimum standards are met, the federal government must respect the Constitution by backing away from implementation of the vote. The Roberts Court argued that racism is over, therefore the Voting Rights Act is no longer necessary to perform this function. The point Roberts made is irrelevant. Apply minimally intrusive standards that are applied equally to ensure fairness and prevent future malfeasance, and it doesn’t matter what the current environment is. This is an entirely acceptable use of the law. Specifically, wouldn’t it be nice to not have to rush or skip voting because of work? Make election day a holiday. Wouldn’t it be nice not to have to travel in inclimate weather to vote? Make election day in the early summer. We’ve introduced early voting and vote-by-mail. Both are extremely popular. Why not keep going? After all, this is about the people, right?

Next, we need to address what got us here. This is actually the ‘Big Kahuna’ of rebuilding America: Education. Republicans have chipped away at public education, ensuring those with money get what they want, and we leftovers get the kind of education we need to be good employees. This is, in fact, how our educational system was adopted. We instituted the Prussian system under Horace Mann in 1843, which was designed to produce obedient workers, not thinkers. We need educational systems that are free from partisan politics, and neighbors, printing “NON-PARTISAN” on the ballot next to a School Board candidate’s name just isn’t doing it. There are other models that work much better (I’ve seen one in Germany – that’s a very promising system thathas vastly improved results over our system.) Americans work hard and we deserve a world class education that focuses on knowledge and growth rather than objective belief. This education must at the very least include critical thinking and rejection of ideological nonsense (suppression of certain topics, and promotion of topics that lack academic rigor). Americans are capable of great things, but to get there, we have to dump the anti-intellectualism and those that promote it. Take that leash off our kids...watch what they can do!

And yes, there’s the economy. We need to fix that too, and guess what? We can do many things at once. We can take care of the bad actors, improve educational opportunities, and we can fix this horribly broken economy. Until people have a steak in the economy, it will continue being pulled by those in economically powerful centers while the rest of us just bump along. Put simply, this starts with ensuring corporations are paying their taxes. The middle and lower classes cannot be expected to prop up the nation while the top 1% continues to live off our efforts. In order to wrap your head around this, you need to shed one simple belief that has been drilled into you since you started paying attention: The poor are not poor because of bad decisions. The poor are poor because the rich control the means of capital distribution in our society. Think about it. How do you get a raise at work? The company decides to give you one. Who sets the price of the gallon of milk? You? No, the corporation sets the price. Extrapolating these two examples, we see exactly our economy is in the position it is in, and why it is so hard to change. The rich determine how much money we are allocated from business activities, and the prices of goods. They literally control both sides of the economic equasion. The wealth gap is a function of the activities of the wealthiest people in America, not the poorest. If we want to apply a fix, we go to the wealthiest in the form of taxes.

Since America just repudiated Republican policies, let’s get specific on one we need to get rid of: ‘no taxes for the rich.’ Unfortunately for the rich, I just cannot feel any empathy. We had periods of high tax rates for the rich: between 1940 and through the 60s, tax rates were well over 50%. Guess what? The rich were still rich. They still had their exclusive hangouts, and yachts, and power, and all that other rich man stuff. They just had to contribute to keeping the country running. And, when you properly allocate resources throughout society, you don’t have to shore up the economy as much. People with money are consumers. Consumers buy things. That props up the industries that people want. That’s how you build an economy. Not by using your power to hoard money and buy politicians. This may even be the simplest of economic moves. It’s so obvious, so basic, even Republicans agree. Remember the $600 check (advance on our future taxes, actually, but…) George Bush and the Republican Congress authorized in 2008? That was an effort to boost the economy. The principle: ‘If the average (99%er) has money, they will spend it.’ Well hang on just a minute, you say... If there aren't any consumers, then how do you have any economy at all, huh? Yeah, there will still be an economy. It just won't include the poor. This is what happened in the 1870s, 1920s, and it's happening again right now.

Now that we’ve hit the big ticket items, there’s one more thing we need to deal with. Can we all agree that Americans live lives that lack dignity? This really is just the everything argument. A lack of healthcare, a lack of job security, being told what you can and cannot do with your body, education, being excluded from government because you talk or look different, treatment my those in power with indifference. This is everything we deal with every day, everywhere. People should be able to get an education and do good in the world with it. People should be able to get healthcare without bankruptcy. They should be able to age in a home where the worker get paid an appropriate wage. They should be able to afford a home. They should be able to live with dignity on the social security that they paid for. They should not be shot in the street because law enforcement have a hard time distinguishing between a gun and a cell phone. Think of it this way: Do you expect reasonable social interactions with people who are made to feel like less than the rest of society? Government is here to do the things that society doesn’t take care of naturally. Time to stop thinking of government as an ogre and rather as a tool to do what it’s supposed to do: help people.

So, we are here at a great inflection point. We opened the door. Now, all that’s left is the hard work: making America into a county that is respected for our principles. The question is, will the Democrats in Congress realize what they are holding in their hands?



Tuesday, July 14, 2026

If at first you don't succeed...

I've written HERE on the facts that demonstrate Trump's claims of election fraud in the 2020 General election are without merit. With the November election edging ever closer, day by day and no ideas on how to turn things around, I suppose it is no surprise that Trump is taking his Fraud Show back on tour. I sense there is more to this than we see, though. This feels very different.

First, this was planned. Remember the FBI raid on the Fulton Co., GA's Elections Office and seized the ballots? That was January 28th, over five months ago. 

Next, The records having now been taken out of the custody of the appropriate authority, the set of ballots taken can no longer be considered trustworthy. (Hyperbole? The FBI wouldn't break the law? They are literally breaking the law right now by not releasing the Epstein files. The administrations is corrupt, and the DOJ is clearly taking its direction from Trump.)

Next, he's specifically trying to challenge seats held by Warnock and Ossoff. Why, when we're so close to an election? I expect it's so they can try to stack Congress in Trump's favor to help in any way they can. We might argue because having Trump's people in the office when the election rolls around, they'd have the incumbent's advantage. That seems pretty weak to me. I think Trump wants the biggest possible majorities in both the houses that if the people happen to reject Trump, he can work with congress to retain power by not seating the new senators and representatives. Now, that said, I don't think that's as relevant (albeit a nice treat) to the speech.

But why the speech in prime time? This is just my theory, so go with me on this for a bit. I don't think Trump gives a rat's ass about the public, and certainly, he doesn't care enough about us to want to show up. But prime time gives him other viewers. Trump saw how close he came to staying in power on the last go around. I suggest he's speaking to the militia groups, patriot wannabes, white nationalists, and the like. He's going to use this speech to stir them up and show them the fraud, so when he needs them (election day? January at the Capitol?), they will be there and ready to crack skulls.

The Court has refused to rein in his behavior. Biden's Attorney General waited too long to start any kind of prosecution. There's not been a single consequence to dissuade Trump from attempting any potentially disastrous act, even a coup. Let's hope I'm wrong.

Sunday, May 17, 2026

Thoughts on Politics 1

I believe I understand why we continue to see absolute fecklessness from the current administration. Consider ICE Barbie's $1.2 mil. commercial ad featuring herself. Think about the recent road trip by the Secretary of Transportation at public expense. Think to all of the indignant speeches by The Director of the FBI while testifying in Congress. And who can forget Bondi's revelation that Trump single-handedly saved 119 million to 258 million lives.


But Duffy's road trip revealed to me a truth of this entire bunch, led by the golden calf man himself. Their view of government is that it all just kind runs itself, and they just need to jump in when there's something they want to do or fix. That's the first part, and its crucial to their lack of success. The second part comes more from Duffy's trip. They have no leadership experience to bear on the tasks that face them, so they fall back to what they know: performance. When the facts aren't on their side, switch to arguing the insane. Be the one that generates the headlines with fallacies of patriotism.


Their failure, as I mentioned, comes from their first misunderstanding. Governments do not just run on their own. In fact, it's quite the opposite. Changes in geopolitics place ever-changing demands on different countries at different times. Left on auto pilot, our nation would collapse. In fact, the role of leadership in the context of national government, and try to anticipate those impactful events and be ready for them.


You can't take away for seven months on a road trip, or weeks-long shooting expeditions, or partying with the hocky team, or golfing, or napping, and expect the minions to 'just keep things going.' That is its own insanity. 

Saturday, April 26, 2025

An Ansible Journey 15: Templates

My final post will walk through the process of using a template to deliver customized files that may vary across hosts, operating systems, applications and so on. The principle is as in the prior posts, not overly difficult. It consists of:

  1. Creating the template file(s)
  2. Creating the variables with changing values to insert in those template files
  3. Adding the play to do the work
  4. Restarting any services once the change is made.

Creating the Template Files

For this exercise, we will be customizing two sshd_config files, one on Rocky Linux and one on Ubuntu. The main difference is in the content of each file. The default Rocky Linux file will not work with Ubuntu, and vice versa. 

We start by creating a templates directory under playbooks/roles/base. In that directory, we need to drop a copy of both versions of the files and give them a name that indicates to which OS they belong:

[ansadm@rocky-1 ansible]$ ls -l playbooks/roles/base/templates/
total 12
-rw-rw-r--. 1 ansadm ansadm 4297 Apr 26 16:11 sshd_config_rocky.j2
-rw-rw-r--. 1 ansadm ansadm 3282 Apr 26 16:11 sshd_config_ubuntu.j2

Ansible uses the Jinja2 templating system to manage templates. Jinja2 files use a .j2 extension.

Next, we will add the same directive to both. The portion of the sshd_config file that we are editing is identical in both versions, so I'll show that just once here:

[...]
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

AllowUsers {{ ssh_users }}
[...]

We're adding the AllowUsers directive which expects a list of usernames, separated by spaces. Since this list could change from one host to another, we'll use a variable to store the individual user names.

Variables

In each of the host variable files, we'll add some additional variables to include a list of users, the name of the template files we created above, and the sshd service name:

Rocky Linux Files:

ssh_users: "ansadm rlohman"
ssh_template_file: sshd_config_rocky.j2
ssh_service_name: sshd

Ubuntu File:

ssh_users: "ansadm rlohman"
ssh_template_file: sshd_config_ubuntu.j2
ssh_service_name: ssh


Now, just prior to copying the files out, the placeholder variable in the templates will be swapped with the ssh_users string. The ssh_template_file variable will be used to select the appropriate file to use as a template.

Adding the Play

in the playbooks/roles/base/tasks/main.yml file, we'll add the following play to execute the task:

- name: Generate sshd_config File from Template
  tags: ssh
  template:
    src: "{{ ssh_template_file }}"
    dest: /etc/ssh/sshd_config
    owner: root
    group: root
    mode: 0644
  notify: restart_sshd

There's nothing here we have not already done. The src parameter accepts a variable in place of the actual template file to use. The ownership and permissions are set according to what the configuration file has in the /etc/ssh directory.

Service Restarts

There is one additional item that we'll need to account for. the service name between the two is also different. Ubuntu uses ssh.service, whereas Rocky uses sshd.service. That is handled by our last variable, ssh_service_name, in the restart_sshd handler. We again use the notify directive to call the handler once the change is registered.

And with that, our configuration for sshd is now templatized (read, quickly and easily customized) for our servers.

<PREV - CONTENTS

An Ansible Journney 14: Host Variables and Handlers

This post covers the use of host variables and handlers. these offer a way to reduce the lines of code used to specify an infrastructure, and to extend the functionality of a play or task.

Host Variables

Host variables are defined in a host_vars directory that resides in your playbooks directory. Each file must be named exactly as the hostname (or IP address/FQDN) in your inventory file. In my host_vars directory, I have three files:

[ansadm@rocky-1 ansible]$ ll playbooks/host_vars/
total 12
-rw-rw-r--. 1 ansadm ansadm 91 Apr 26 15:18 192.168.5.250.yml
-rw-rw-r--. 1 ansadm ansadm 87 Apr 26 12:48 192.168.5.251.yml
-rw-rw-r--. 1 ansadm ansadm 88 Apr 26 12:51 192.168.6.30.yml
[ansadm@rocky-1 ansible]$

Although these files all have a .yml extension, the use of "---" on the first line is optional. Within that file, we specify each variable using a key/value pair syntax:

[ansadm@rocky-1 ansible]$ cat playbooks/host_vars/192.168.5.250.yml
---
nginx_package_name: nginx
nginx_service_name: nginx
extra_package_name: pcp-pmda-nginx

Once your variables file is created, you can reference the individual variables using Ansible's variable syntax:

"{{ variable-name }}"

In our web_servers role, our first task instructs the dnf module to install two packages, nginx and pcp-pmda-nginx:

- name: Install Nginx Web Service
  tags: nginx,web
  dnf:
    name:
      - nginx
      -
pcp-pmda-nginx
    state: latest
 

with the host variables file shown above, we can obtain the same result referencing the variable names:

- name: Install Nginx Web Service
  tags: nginx,web
  dnf:
    name:
      - "{{ nginx_package_name }}"
      - "{{ extra_package_name }}"

    state: latest

Upon execution, Ansible will replace "{{ nginx_service_name }}" with "nginx."

In a case where the same variable may have a different value across different operating systems, we could specify the same variable name with different values in each host variable file, and Ansible will perform the correct replacement. Thus, we've reduced the side of the play, and extended it to work in more situations.

Handlers

Handlers offer a way to reuse task functionality. In an earlier post, we built a restart_nginx play that checked variable, nginx_conf, to see if it registered a change. If so, then we called the restart Nginx play using a when clause:

when: nginx_conf.changed

This works well, but there may be other reasons to restart our web server that have nothing to do with the configuration file. Without a handler, we would need to write a second restart Nginx play that is called when a different variable registers the change.

To create a handler, we need to start with a directory under the role of our choice called handlers:

playbooks/
    roles/
        web_servers/
            handlers/
                main.yml

As you can see, our handler, like our task book is stored in a file called main.yml. The code for our restart Nginx handler is:

- name: restart_nginx
  service:
    name: "{{ nginx_service_name }}"
    state: restarted

Going back to the play that calls the handler, we'll replace the register: nginx_conf line with a notify directive that calls the handler by name:

 - name: Enable HTTPS in Nginx
  tags: nginx,web
  lineinfile:
    path: "/etc/nginx/nginx.conf"
    line: "        listen       *:443 ssl;"
    insertafter: 'listen       80'
    firstmatch: true
    backup: true
  notify: restart_nginx

The advantage here is that we can call the handler from any code in the web_server role.

 

<PREV - CONTENTS - NEXT>

An Ansible Journey 13: Roles

Roles provide the user will separating out different blocks of code for ease of reading. In this context can be thought of as the role that the target server plays in the environment. They allow you to move code into other files, keeping the playbook cleaner. Fortunately, using roles doesn't restrict you from categorizing work; you can still have, for example, a role called web_servers and still differentiate between say, a web server that is public-facing and a web server for internal use (which may have relaxed security requirements).

In one of the earlier videos, Jay split up his playbook into two two: the bootstrap.yml file and the site.yml. Roles takes this a step further.

Creating roles is very straight-forward, requiring only two general modifications to a playbook with all tasks in one file: directory structure changes and moving code blocks to a new file or files.

Directory Changes

Roles imposes a standard for using roles in your filesystem. In general, no directory is required unless there are files in that directory. Here is an example:

opt/
    ansible/
        inventory/
        playbooks/
            site.yml
            roles/
                base/
                files_servers/
                    tasks/
                        main.yml
                web_servers/
                    files/
                        landing_page.yml
                    tasks/
                        main.yml

Under playbooks we create a directory called roles. That contains a directory for each server role we are defining. The base role is one that would likely apply to all servers, containing such items as the implementation of organizational security policies, support team configurations, etc. Within each role, we have at a minimum, a tasks directory. We can optionally add additional directories, like files, if there are files that we will be transferring to our target servers. Finally, within each tasks directory, we have a file called main.yml. The directory corresponding to a role is required, as is the tasks directory, and the main.yml file.

Code Changes

In the previous model, we created roles by using the [role-name] construct in our playbook:

playbook.yml file
    [base]
        (plays intended for all hosts)
    [web_servers]
        (plays intended for all web servers)
    [db_servers]
        (plays intended for all database servers)
    [file_servers]
    ...

The playbook.yml file will have all plays removed, with each set of plays being defined in its respective main.yml file underneath tasks:

playbook.yml file:

- hosts: all
  become: true
  pre_tasks:
    (any plays that will be run on any server, with each run.*)

- hosts: all
  become: true
  roles:
    - <rolename>
...

main.yml file

- name: Install Nginx Web Service
  tags: nginx,ubuntu,web
  apt:
    name:
      - nginx-core
      - nginx-doc
    state: latest
  when: ansible_distribution == "Ubuntu"

- name: Enable HTTPS in Nginx - Rocky
  tags: nginx,rocky,web
  lineinfile:
    path: "/etc/nginx/nginx.conf"
    line: "        listen       *:443 ssl;"
    insertafter: 'listen       80'
    firstmatch: true
    backup: true
  when: ansible_distribution == "Rocky"
  register: nginx_conf
... 

The playbook.yml file retains each section it did before, but we replace the plays with:

  roles:
    - <rolename>

Then, we take the plays that were in the playbook.yml file and place them into the main.yml file. We'll retain the tags so we can continue to narrow the scope of each run during testing, quick patch activity, etc. One thing to note that is not clear in the example is that whereas the plays are indented two spaces in the playbook.yml file, they start on the left (column 1). This is due to the YAML requirement that all code begin on the left. Note that the first line of our playbook.yml file (---) is not required in the main.yml files.

The main.yml file (and any other collection of plays) in the tasks directory are referred to as "taskbooks."

 

<PREV - CONTENTS - NEXT>

Friday, April 25, 2025

An Ansible Journey 12: Managing Users

Starting Notes

First, I ran across a missing Ansible collection [of modules] while working through this video. Specifically, the authorized_key module was missing. After a short search, I was able to drop the collection on the server with the following command:

ansible-galaxy collection install ansible.posix

Once done, I could deploy the keys.

Next, the author added a line in this video:

changed_when: false

to two of the commands in the bootstrap.yml file. I received errors from Ansible when adding this line, so I removed it. By watching the video, you can see the impact of removing this line, which is rather trivial.

Finally, I've rewritten the entire access and permissions parts. The method employed by the author is good for setting up a small lab, but in my case, I tend to work from a large enterprise perspective, and the manual work required to prepare an Ansible user account simply does not scale well to hundreds or thousands of servers.

User Management

User management is actually very straight forward, and the plays are rather easy to understand. We will start by creating an application user account. It is customary to run applications with service accounts that have restricted permissions. In this case, we are creating a user account to run the billing application. The application and user are part of the accounting group, so we will first be sure that the accounting group exists.

- name: Ensure Group "accounting" Exists
  group:
    name: accounting
    state: present
    gid: 5006

- name: Ensure User svc_billing Exists on Servers
  tags: always
  user:
    name: svc_billing
    groups: accounting
    shell: /sbin/nologin
    state: present

The accounting group in this case is called, well, accounting. We want it to be present, and we manage group ids also, so we'll want to specify that gid.

Next we create our service account, svc_billing. We use groups to force that account to be a member of the accounting group. Since this is a service account, we don't expect anyone to actually use it for a login, so we disable logins for that account.

Now we'll move on to an administrative user account. That account will need extra authority to execute commands. Since permissions are maintained in our fictitious company at the group level, we need to be sure the group is available first, and that is has the appropriate sudo permissions.

 - name: Ensure Group "support" Exists
  tags: always
  group:
    name: support
    state: present
    gid: 5007

- name: Ensure sudoers File is in Place
  tags: always
  copy:
    src: /opt/ansible/files/sudoers/sudoer_support
    dest: /etc/sudoers.d/support
    owner: root
    group: root

For this to work, we'll need to create the file to copy over with the actual sudo entry. The path and filename are above. The content consists of a single line:

%support ALL=(ALL) NOPASSWD: ALL

Now that we are confident our group will be available, we can create our user account:

 - name: Ensure Admin User Account jdoe is Available
  tags: always
  user:
    name: jdoe
    groups: support
    state: present

- name: Add SSH key for User jdoe
  tags: always
  authorized_key:
    user: jdoe
    key: "ssh-rsa AAAAC3dsfSDF9a79kll0[...]REsd9fdfkjRGLDSFGJ jdoe"

Here, we create the jdoe user, assign and tag the account as a system account. We also assign them to the support group. We also take their public key and add to the authorized_key files in any accounts that are created. We assume jdoe has just become part of the organization, and issued the ssh-keygen command to create their own public/private key pair, and pasted their public key in the play.

 

<PREV - CONTENTS - NEXT>