24 | MMM. .MMM
25 | MMMMMMMMMMMMMMMMMMM
26 | MMMMMMMMMMMMMMMMMMM ____________________________
27 | MMMMMMMMMMMMMMMMMMMMM | |
28 | MMMMMMMMMMMMMMMMMMMMMMM | Keep it logically awesome. |
29 | MMMMMMMMMMMMMMMMMMMMMMMM |_ ________________________|
30 | MMMM::- -:::::::- -::MMMM |/
31 | MM~:~ 00~:::::~ 00~:~MM
32 | .. MMMMM::.00:::+:::.00::MMMMM ..
33 | .MM::::: ._. :::::MM.
34 | MMMM;:::::;MMMM
35 | -MM MMMMMMM
36 | ^ M+ MMMMMMMMM
37 | MMMMMMM MM MM MM
38 | MM MM MM MM
39 | MM MM MM MM
40 | .~~MM~MM~MM~MM~~.
41 | ~~~~MM:~MM~~~MM~:MM~~~~
42 | ~~~~~~==~==~~~==~==~~~~~~
43 | ~~~~~~==~==~==~==~~~~~~
44 | :~==~==~==~==~~
45 |
46 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Example GitHub Actions workflow with Flux and Amazon EKS
2 |
3 | An example workflow that uses [GitHub Actions](https://help.github.com/en/categories/automating-your-workflow-with-github-actions) to build [a static website](app/site/) into a Docker container, push that image to Amazon Elastic Container Registry, and uses [Flux](https://www.weave.works/oss/flux/) to automatically update an existing Amazon Elastic Kubernetes Service cluster with that image.
4 |
5 | See this [technical blog post](https://www.weave.works/blog/gitops-with-github-actions-eks) which uses this code for full step-by-step instructions.
6 |
7 | ## Prerequisites
8 |
9 | 1. Create an EKS cluster, e.g. using [`eksctl create cluster`](https://eksctl.io/)
10 | 2. Set up Flux on the cluster, e.g. using [this guide](https://docs.fluxcd.io/en/1.20.0/get-started). Note that you must set `--git-path` to point to where your manifests are. For example:
11 | ```bash
12 | export GHOWNER=
13 | export GHREPO=example-actions-flux-eks
14 |
15 | kubectl create ns flux
16 |
17 | fluxctl install \
18 | --git-user=${GHUSER} \
19 | --git-email=${GHUSER}@users.noreply.github.com \
20 | --git-url=git@github.com:${GHOWNER}/${GHREPO} \
21 | --git-path=manifests \
22 | --namespace=flux | kubectl apply -f -
23 | ```
24 | 3. Give Flux read/write access to the GitHub repository [using a deploy key](https://docs.fluxcd.io/en/1.20.0/tutorials/get-started/#giving-write-access)
25 | 4. Create a repository called `example-eks` in [Amazon Elastic Container Registry](https://docs.aws.amazon.com/AmazonECR/latest/userguide/Registries.html), in the same AWS region as the EKS cluster
26 | 5. Update the image in [`deployment.yml`](manifests/deployment.yml) to use your `REGISTRY`, `IMAGE`, and `TAG`. `TAG` will be replaced by Flux as new images are available in the registry.
27 |
28 | ## Secrets
29 |
30 | The following secrets are required to be set on the repository:
31 |
32 | 1. `AWS_ACCOUNT_ID`: The AWS account ID that owns the EKS cluster
33 | 1. `AWS_ACCESS_KEY_ID`: An AWS access key ID for an account having the [EKS IAM role](https://docs.aws.amazon.com/eks/latest/userguide/service_IAM_role.html)
34 | 1. `AWS_SECRET_ACCESS_KEY`: An AWS secret sccess key for an account having the [EKS IAM role](https://docs.aws.amazon.com/eks/latest/userguide/service_IAM_role.html)
35 |
36 | ## Workflow
37 |
38 | The [example workflow](.github/workflows/build.yml) will trigger on every push to this repo.
39 |
40 | For _pull requests_, the workflow will:
41 | 1. Build and tag [the Docker image](app/Dockerfile)
42 | - The image will be tagged with the feature branch's HEAD commit SHA
43 |
44 | For _pushes_ to the default branch (`master`), in addition to the above, the workflow will:
45 |
46 | 1. Push the image to Amazon Elastic Container Registry
47 |
48 | ## Beyond the workflow
49 |
50 | Flux watches ECR for changes to the image listed in our [deployment configuration](manifests/deployment.yml). When it detects a change, it updates the EKS cluster with the new image, no manual `kubectl apply` needed!
51 |
52 | ## Contributions
53 |
54 | We welcome contributions! See [how to contribute](CONTRIBUTING.md).
55 |
56 | ## License
57 |
58 | [MIT](LICENSE)
59 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to make participation in our project and our
7 | community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and
9 | expression, level of experience, education, socio-economic status, nationality,
10 | personal appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | - Using welcoming and inclusive language
18 | - Being respectful of differing viewpoints and experiences
19 | - Gracefully accepting constructive criticism
20 | - Focusing on what is best for the community
21 | - Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | - The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | - Trolling, insulting/derogatory comments, and personal or political attacks
28 | - Public or private harassment
29 | - Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | - Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or reject
41 | comments, commits, code, wiki edits, issues, and other contributions that are
42 | not aligned to this Code of Conduct, or to ban temporarily or permanently any
43 | contributor for other behaviors that they deem inappropriate, threatening,
44 | offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies within all project spaces, and it also applies when
49 | an individual is representing the project or its community in public spaces.
50 | Examples of representing a project or community include using an official
51 | project e-mail address, posting via an official social media account, or acting
52 | as an appointed representative at an online or offline event. Representation of
53 | a project may be further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at
59 | opensource+github-developer/example-actions-flux-eks@github.com. All complaints will be reviewed
60 | and investigated and will result in a response that is deemed necessary and
61 | appropriate to the circumstances. The project team is obligated to maintain
62 | confidentiality with regard to the reporter of an incident. Further details of
63 | specific enforcement policies may be posted separately.
64 |
65 | Project maintainers who do not follow or enforce the Code of Conduct in good
66 | faith may face temporary or permanent repercussions as determined by other
67 | members of the project's leadership.
68 |
69 | ## Attribution
70 |
71 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
72 | version 1.4, available at
73 | https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
74 |
75 | [homepage]: https://www.contributor-covenant.org
76 |
77 | For answers to common questions about this code of conduct, see
78 | https://www.contributor-covenant.org/faq
79 |
--------------------------------------------------------------------------------
/app/site/css/main.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v2.1.3 | MIT License | git.io/normalize */@import url(//fonts.googleapis.com/css?family=Inconsolata:400,700|Montserrat:700);article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden],template{display:none}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}a{background:transparent}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:0.67em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace, serif;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}html{font:16px/1.5 Inconsolata, sans-serif}@media (min-width: 30rem){html{font-size:20px}}body{margin:2rem 0 5rem;color:#333}@media (min-width: 30rem){body{margin-top:5rem}}a{color:#0074d9;text-decoration:none}a:hover,a:focus{text-decoration:underline}h1,h2,h3,h4,h5,h6{font-family:Montserrat, sans-serif;margin:0 0 0.5rem -0.1rem;line-height:1;color:#111;text-rendering:optimizeLegibility}h1{font-size:2.5rem;margin-bottom:1rem}@media (min-width: 30rem){h1{font-size:3rem;margin-bottom:3rem}}h1 a{color:inherit}h2{margin-top:2rem;font-size:1.25rem;margin-bottom:0.75rem}@media (min-width: 30rem){h2{margin-top:2.5rem;font-size:1.5rem;margin-bottom:1rem}}h3,h4,h5,h6{margin-top:1.5rem;font-size:1rem;text-transform:uppercase}p,ul,ol,dl,table,pre,blockquote{margin-top:0;margin-bottom:1rem}ul,ol{padding-left:1.5rem}dd{margin-left:1.5rem}blockquote{margin-left:0;margin-right:0;padding:.5rem 1rem;border-left:.25rem solid #ccc;color:#666}blockquote p:last-child{margin-bottom:0}hr{border:none;margin:1.5rem 0;border-bottom:1px solid #ccc;position:relative;top:-1px}.container img,.container iframe{max-width:100%}.container img{margin:0 auto;display:block}table{width:100%;border:1px solid #ccc;border-collapse:collapse}td,th{padding:.25rem .5rem;border:1px solid #ccc}pre,code{font-family:inherit;background-color:#eee}pre{padding:.5rem 1rem;font-size:0.8rem}code{padding:.1rem .25rem}pre>code{padding:0}.container{max-width:30rem;margin:0 auto;padding:0 1rem}.hll{background-color:#ffc}.c{color:#999}.err{color:#AA0000;background-color:#faa}.k{color:#006699}.o{color:#555}.cm{color:#0099FF;font-style:italic}.cp{color:#099}.c1{color:#999}.cs{color:#999}.gd{background-color:#FFCCCC;border:1px solid #c00}.ge{font-style:italic}.gr{color:red}.gh{color:#003300}.gi{background-color:#CCFFCC;border:1px solid #0c0}.go{color:#aaa}.gp{color:#000099}.gu{color:#003300}.gt{color:#9c6}.kc{color:#006699}.kd{color:#006699}.kn{color:#006699}.kp{color:#069}.kr{color:#006699}.kt{color:#007788}.m{color:#f60}.s{color:#d44950}.na{color:#4f9fcf}.nb{color:#366}.nc{color:#00AA88}.no{color:#360}.nd{color:#99f}.ni{color:#999999}.ne{color:#CC0000}.nf{color:#c0f}.nl{color:#99f}.nn{color:#00CCFF}.nt{color:#2f6f9f}.nv{color:#033}.ow{color:#000000}.w{color:#bbb}.mf{color:#f60}.mh{color:#f60}.mi{color:#f60}.mo{color:#f60}.sb{color:#c30}.sc{color:#c30}.sd{color:#CC3300;font-style:italic}.s2{color:#c30}.se{color:#CC3300}.sh{color:#c30}.si{color:#a00}.sx{color:#c30}.sr{color:#3aa}.s1{color:#c30}.ss{color:#fc3}.bp{color:#366}.vc{color:#033}.vg{color:#033}.vi{color:#033}.il{color:#f60}.css .o,.css .o+.nt,.css .nt+.nt{color:#999}
--------------------------------------------------------------------------------