spieler guardiola - all charm!
E s gibt da diesen Raum, der Thomas Krücken besonders in Erinnerung geblieben ist. Und was sie sahen, prägt sie bis heute. Juli an nicht mehr viel weiterhelfen. Manchester City gewinnt auch dank des Treffers des deutschen Stürmers mit 3: Helft mit und finanziert zusammen mit BigShoe lebenswichtige Operationen für Kinder. Aber auch einige faustdicke Überraschungen. Es ist viel vom Halbfinale gegen Real Madrid gesprochen worden. Man muss also alles daran setzen, die Physis im bestmöglichen Zustand zu erhalten.
These spaces are where City, alongside many other teams, are trying to target with their play. Ederson is competent in his short- and medium-length passing, sometimes struggling when it comes to playing passes on the first touch into tight areas.
However, Ederson has an edge over Bravo, and every other goalkeeper in the world, in long-range distribution. These passes have excellent accuracy that find their intended target at a high frequency.
For a lack of a better comparison, he is the Paul Scholes of goalkeepers, with an equal propensity for physical play on the defensive side of the game.
Consequently, City have a higher versatility when it comes to ways that they can break through opponents from their deep build-up, particularly against opponents who employ a high press.
As mentioned earlier, most domestic opponents tend to drop off versus Manchester City, not challenging in the first phase of possession. For those that wish to engage them during goal kicks, Ederson expands the possible solutions with his passing range.
If an opponent steps up towards the centre-backs and crowds the first third of the pitch, Ederson introduces the capability of beating pressing schemes by playing over them and avoiding them entirely.
Ederson can then find them on the aerial pass with remarkable timing, bypassing the opposition press and playing over the majority of the opponents with one pass.
As Ederson places the ball down for a goal-kick, the opponents move up to high pressure City, expecting them to play short. Sensing this, the front three players of City move up, knowing Ederson can reach them and that they cannot be offside on a goal kick.
A large gap is created centrally, and Ederson spectacularly plays it to Sterling. When opponents begin to anticipate this, large gaps between the opposition players will form centrally around the centre circle, providing space for City players to move into as well in order to break the press.
Ederson is more than capable of playing chipped passes that find the option in this area, giving City yet another option of how they can evade high pressing opponents.
As the saying goes, there is more than one way to skin a cat. City are versatile when it comes to finishing what they created by building up and moving the ball up the field.
They can pass through the vertical gaps, play the diagonal ball from the outside behind the back line, use set-pieces or counter-attack like there is no tomorrow.
Nothing is surprising about the fact a top-team like City with high-level midfielders and forwards can do it all. What has stuck out this season is how they have made use of low crosses.
Using the wings may not be something that comes immediately to mind when thinking about a Guardiola side, but he knows how to use his attacking players.
Several goals have been scored after City broke through to the touchline and crossed the ball low into the centre. Sometimes the assist had the typical attributes of a cross, which means it was a rather lateral ball.
Sometimes the assist was rather played like a backwards pass. Sometimes both were combined; just watch their third goal against Stoke City.
What is needed to be able to play a low cross is dynamic and usually a bit of an opening. Another setup for the low cross has usually been the half-space run by one of the full-backs.
Particularly on the right side, where De Bruyne often is found wide as the Belgian drifts to the touchline and takes on the opposing full-backs, Walker has the chance to travel through the inside lane and receive the ball in the back of the defender.
When Walker did not make the run or was not in position fast enough in some of the matches, De Bruyne sometimes just punted the ball into the box.
That also happened occasionally after longer possession spells without any substantial progress. Dynamic is needed to create the right environment for the breakthrough and the low cross.
The fact they are so hard to break down is the result of a developmental process. When the season started, City were not looking like an unconquerable stronghold.
The pressing scheme was man-oriented, the intensity not quite on the level they needed it to be. The first line of pressing tried to work aggressively and block the lanes, while there was no deliberate intention to force turnovers early on.
Since the back line was steadily moving backwards, the area behind De Bruyne and Silva was growing. Especially within the first few yards behind the halfway line, City intended to interrupt any passing flow and stop the progress of the opposing play.
Since City often missed the opportunity to guide the build-up towards the touchline, they remained reactive and, therefore, could not always prevent every pass into the space behind the midfielders which then often caused danger for their own goal.
Around the halfway line, City pushed the two lines together, while the ball-near full-back moved forward. Deeper into the season, City started using curve-runs up front more frequently in order to set up pressing trap.
If they are not able to successfully force the early turnover, City typically transition into a , with the two wingers dropping back on the outside lanes to potentially have double coverage there.
The third phase of pressing sees them in a , as the two centre-midfielders move back and join Fernandinho to close down the middle.
The amount of mistakes committed in terms of positioning has declined. Early on, however, City players showed the tendency of moving into the wrong zones or towards the wrong opponents at the wrong time, which the example in the graphic below illustrates.
During their first match against Crystal Palace, that situation occurred. Even though Sterling made the right move and put Patrick van Aanholt 3 in his cover shadow, Walker decided to go wide instead of threatening Jeffrey Schlupp Those mistakes became rare as the season went on.
In addition to that, the centre-backs strictly stuck to man-marking in some of the earlier matches which, considering the general high line City employed due to the long spells of possession, made them more prone to being pulled away and caught out of position.
Fernandinho was able to smooth some of these situations out, but that caused him to be less present in the no. As pointed out above, City usually deploy a in the third phase of pressing.
The issue can be that they hold back and remain passive with the intention to just block the zones of importance.
Without any pressure put on the ball carrier, it can lead to situations like that one, in which Taison 7 broke the line while Fred 8 escaped Silva and was only stopped by a tremendous Fernandinho tackle.
City did still not allow comparatively much in their defensive third during the first quarter of the Premier League season and continued to do so after the end of October.
The number even dropped to 1. Not one other Premier League team came even close to that. Over time, City have become far more versatile in how they set up their pressing.
A striking example was their home match against Shakhtar in late-September, in which instead of employing the typical centre-forward-vs-centre-back setup, City made use of the two wingers to make curve-runs towards the two Donezk defenders in the middle.
There was not much Ivan Ordets 18 could have done differently, since he apparently did not want to just punt the ball forward and cause a transition attack through the middle.
Jesus was probably not even visible as he hid behind Fred. He could not control the ball, but it nevertheless shows how City can utilise these traps with their high press.
City, however, did not become impetuous due to the increased intensity in the first phase of pressing. The second phase of pressing was again focussed on stability and the prevention of passes through the half-spaces or the middle of the field.
The two centre-midfielders, in particular, had to prove how they have an understanding of transitioning from a high to a midfield press.
Giving up the high press and falling back into a more compact shape to contain the opponents who just outplayed you requires a high football IQ, and, of course, the right coaching.
Both are asked to move up the field and block the opponents on the wing repeatedly, for which they not only need the timing and stamina, but also the feeling for how to use body postures in order to prevent the opponents from bypassing them.
Both Delph and Walker have proven they can provide just that over and over again. Usually, the two full-backs start from a position similar to the one Fernandinho typically has, as far as height on the pitch is concerned.
Fernandinho usually dropped back and took over the initial zone the centre-back was assigned to cover. There have been only a few examples when City did not use their full-backs in that kind of aggressive role; one was in their win over Napoli in mid-October.
In that match, Walker und Delph apparently had the job to mark the two advanced wingers instead of pressuring the full-backs.
In the Napoli match, however, they were barely a factor in the early phase of pressing. Tieing them up would likely create space next to Fernandinho.
While the Brazilian has a high defensive range, he could never cover a real estate as wide as 30 or so yards at once. It might force Silva and De Bruyne to drop back, which would then decrease the intensity of the high press.
Or there would be an opening to exploit and enter the middle third. But since only a few teams have even attempted to use high wingers against City strategically, we probably have to wait for the Champions League knockout stage to find an answer to how Guardiola would react and adjust the pressing scheme.
These typical three-point build-up plays can be shut down fairly easily. Positioning two wingers high up the pitch may force the City full-backs to hold back.
But there is probably a downside to that. In order to use two wingers and keep the centre-midfielders busy, the City opponents have to rely on two build-up players at the back, which would create more distance for lateral passes.
And as Domenico Tedesco recently pointed out in an interview he gave us, the ball is loose for a moment which is the best time to pressure.
The times in which City have either just lost or recovered possession define their style of play as much as their moments in possession.
While many goals have been scored through counter-attacks this season, their approach to defending counter-attacks and chasing the ball after losing possession sets them apart from the rest of England.
While a sophisticated possession style, particularly on the Guardiola level, typically minimises the threat of being hurt by transition attacks, there will remain a slight vulnerability that even the best counter-pressing would never fully solve.
Just like in the pressing department, City needed a few matches to find their groove and establish a forceful counter-press.
At first, a mix of mediocre decision-making and lack of compactness between midfield and attackers line hindered them from regaining possession quickly.
Two important factors have changed that: Second, the sophisticated use of a false full-back has helped to switch from a shape behind the three forwards to a shape, allowing the two advanced midfielders to have a higher position in general, without having to be concerned about the space behind them.
It has also given the two midfielders the option to attack one half-space collectively, thus using more pressure to interrupt transition attacks or having a better chance to react to overloads.
This is how it should not be done. Instead of preparing a potential counter-press before Sterling received the ball, City just let their winger be trapped within a pack of Crystal Palace players which then ultimately led to a dangerous counter-attack, because the half-space was not protected.
This is how City often set up their counter-press these days. Because the inverted full-back provides more protection in the no.
Early on, City occasionally struggled to regain possession as quickly as intended. The two midfielders forced isolated duels, while backwards pressing seemed far from impactful.
Too often, the ball-near forward was on the wrong side of the ball carrier and just hastily attempted to pressure the opponent, with his team-mate in front of the ball not knowing how to read what the forward tried to do.
What City helped to avoid any destabilisation due to said issues in regards to compactness and coordination was smart damage control. They always switched from counter-pressing to pressing within a short time frame.
Instead of not letting it go and keeping the counter-pressing setup, they usually quickly transitioned into the midfield press. Previous Guardiola sides have had the seconds after losing possession be key hallmarks of their game model.
At Manchester City, Guardiola has instilled counter-pressing focused on eliminating the passing options for the player in possession in the shortest amount of time possible.
After having lost the ball to Bournemouth, City tried to immediately win it back, although they did not have enough presence around Andrew Surman 6 who played the lateral pass to avoid the turnover.
City did not go for another attempt but transitioned into their usual pressing formation to utilise the practised schemes.
The name may suggest otherwise, but the players participating in rest-defence are not necessarily resting.
This concept illustrates how the structures between attacking and defence are symbiotic. In order to prevent harmful counter-attacks, Guardiola organises his team in possession so that when possession is lost, they are adequately balanced to deal with transitions that happen to break through the initial counter-press.
If there are two strikers up high, City will keep three behind the ball providing cover. When three are held up, four will stay behind, and so on.
When the two centre-backs are in need of support, it comes from the far side full-back most often. For instance, if City are attacking down the left side of the pitch, Walker will help cover for the centre-backs.
Fernandinho will reside in front of the first line of defence preventing anything down the middle, with a distance occupied that can have him move into a covering spot if needed.
By putting these players centrally, the only option for effective counter-attacking for the opponents is by going around them.
When outnumbered, City will be able to apply pressure with more than one person and easily win the ball back given the athleticism and abilities of their defenders individually.
If a team cannot play an attacking option into feet centrally, then they must play into space in order to have a shot at catching the Citizens on the break.
If it is not, either the pass is too meek and it can be intercepted, or the pass is too long so that it runs out of range of the forward and the ball is collected by Ederson.
When forced to the touchline, the playing angle for the player on the ball decreases by degrees, as turning away from the play will lead the player to go out of bounds.
However, especially against top opponents, City have been forced to quickly transition into defence in their defensive third of the pitch.
Between the right and left full-backs, there can be no more than ten yards at times. Similar to the logic behind their rest-defence, such a scheme forces any passes to be played around them.
Due to the congestion of bodies around the ball, shots from distance are blocked, and the only open option is wide, which presents much less danger than anything central.
This makes it so any shot that is taken by a player in the centre is likely blocked by one of the four defenders. Any passes that are played into team-mates in the half-spaces can have pressure applied by one of the defenders, and any shot they take comes from a less probable angle of scoring than the central one.
The immediate priority is delaying the opponent from shooting and having the midfield recover. The next aim is to back-press and win possession, or to coerce the next pass to be played backwards, during that time City step their lines up and move into their standard defensive shape.
Early on in his career, Guardiola sparingly had his teams counter attack, preferring to use the transition period to have his team get organised into their attack structure.
Nowadays, his team are one of the most effective sides on the counter in Europe. Rather than aiming to counter whenever possible, City wisely pick their moments to unleash their weapons when their opponents are spread out during their attack.
In most attacking shapes throughout the Premier League, the midfield and attack are spread out in an effort to create as much space as possible for every player.
Conversely, this means when City win the ball, their opponents have a large amount of space to make up in order to apply pressure to the ball or recover into their defensive position.
The moments when the Citizens recover possession then offer the most amount of space as a result. Having a large amount of space available to attack means little if the players on the pitch do not recognise it and act quickly.
City understand this notion during their play, which explains their remarkably fast reactions when moving from one phase to the other.
When the ball is won and there is a strong counter-attacking opportunity, the attacking players immediately start their runs towards goal, running at full speed towards their destination.
The ball has not been played yet though and is most often in the midfield at this point. Considering the angles of the runs and the time available to pick out the pass, the player on the ball is spoiled for choice.
Regardless of the option he chooses, he has to weigh the pass just right so that the pass arrives to the targeted area when the player does. These passes played lead the runner towards the goal, either centrally or from width.
When played centrally, the pass typically goes in between the opposing centre-backs, often leading the striker right to the goal and a breakaway with the goalkeeper.
If one of the other options is chosen, the pass sets up an opportunity from a low cross to be played across the goal mouth, leading to an easy finish when pulled off correctly.
In either case, City have their opponents on their heels. Due to the blistering speed of the attack and the supporting runners, there are at least three players joining for the counter-attack.
In the instance that a player does not wish to shoot when close to the goal, they can play a pass and likely there will be someone there to finish a tap-in.
Regardless of the outcome, the overall speed and quick reflexes of the Citizens places them as one of the top counter-attacking clubs in England.
Many goals throughout the season have come from their attacking transitions, notably in their routs against Stoke, Liverpool, and Tottenham.
It is yet another dimension in how City have decisively beat those who have come across them throughout the season. From moments of crisis come opportunity, and Delph has taken advantage of this.
In the span of a few months, he has risen up to become first-choice left-back through his consistent and added stability.
In the role of a false full-back, rather than primarily be positioned near the wing, the player will move towards the half-spaces and central areas of the field.
This role increases the central presence during build-up and circulation, allowing other players to be moved higher up the pitch in possession.
In addition, having this player located centrally in rest-defence bolsters defensive transition efforts. If opponents counter-attack at high speed, the space afforded to them is wide areas due to the congestion in the middle.
This is less of an immediate threat than conceding space in the middle, which gives City more time to recover into their defensive shape in case their counter-pressure is broken.
For example, if Ederson has the ball, any player wishing to press him and simultaneously block off the centre with his cover shadow must account for two players instead of one.
If there were no additional option centrally, eliminating Fernandinho would be much easier for the opponents. Ederson would be forced to play sideways and make build-up more wing-focused for City.
Alternatively, the goalkeeper would play long and hope City win the aerial duel, an option that relies much more on luck than protecting the ball via stable possession.
With the false full-back moving centrally, the remaining defenders will adjust accordingly. Since the false full-back is most frequently from the left side, the left-sided centre-back—most often Otamendi, sometimes Eliaquim Mangala—will slide out towards the left more, stopping at about the width of the penalty area.
The other central defender, whether it be Stones, Kompany, or another player, will slide centrally, while the right full-back will behave as a right-sided centre-back in a back three if needed.
If the opponents are defending very deep, the other full-back will move up as well to prevent an excessive build-up of players in rest-defence.
As the opponents pressure high, Delph recognises the gap in the centre and abandons the traditional position of a full-back in favour of moving inside.
Once Ederson plays him the pass, Silva moves to the touchline to free up space for Delph to dribble forward. Moving Delph inside allows him to play a position and role familiar to him, assisting in build-up to give Fernandinho an additional player on the same line to help with circulation in the attacking half.
This, in turn, eliminates the need for Silva and De Bruyne to come deep to receive the ball, and they can receive the ball more in the creative positions closer to the opposition goal.
It also complicates the shifting of the opposition in defence, as the shorter horizontal passes during circulations force the opponents to make decisions about whether to cover the diagonal passing options, such as the one of the no.
When Delph is higher up the pitch, he is valued in possession for City. The year-old uses his body, particularly his back, excellently when protecting the ball, getting out of tight situations using quick shifts of weight and direction changes.
This explains how he is resistant to pressure and able to play in tight spaces. However, it is not exclusively Delph who plays the false full-back role.
Danilo has slotted into that role at various points throughout the season, most notably against Swansea City in December.
Guardiola interprets the role differently for the Brazilian, and he ends up having different responsibilities as a result.
The reserve team serves mainly as the final stepping stone for promising young players before being promoted to the main team. In the —08 season they qualified for the newly founded 3.
Liga , where they lasted until when they were relegated to the Regionalliga. This ended 33 consecutive years of playing in the highest league that the German Football Association permits the second team of a professional football team to play.
Es ist viel vom Halbfinale gegen Real Madrid gesprochen worden. Die torschützenkönige der bundesliga Meisterschaft wurde verteidigt. Kürzlich erzählte uns Lionel Messi von Ihrer Detailverliebtheit. Wenn man seinen Körper als Arbeitswerkzeug benutzt, sind Pausen und die Ernährung von grundlegender Bedeutung. Guardiola stammt aus Santpedorwo seit der örtliche Sportplatz seinen Namen trägt. Ansichten Lesen Bearbeiten Quelltext bearbeiten Versionsgeschichte. Man muss also alles daran setzen, die Physis im chinesische mauer düsseldorf Zustand zu erhalten. Fünf Tore testspiel england frankreich 45 Minuten! Trotz em portugal wales Erfolge lebte Ept dublin zurückgezogen, gab so gut wie nie Interviews und versuchte, jede Form von unnötiger Publicity zu vermeiden. Er erhielt einen bis zum Als Neunter landete er sports tracker ohne anmeldung Brescia nur einen Platz hinter der Roma, war aber im Tabellenmittelfeld trotzdem lediglich vier Punkte von einem Abstiegsplatz entfernt. Nun steht das Team des Jahres Nicht die erste Panne des Verteidigers. WM in Russland. Eigentlich ist diese Phase im Turnier die schwierigste, mehr noch als das Finale. Im Angriff benötigt man aber eine alternative bet3000 Messi und Suarez.
Pep Guardiola exposed: How he fools players and the media MestallaValenciaSpain. He became a first-team regular in the —92 seasonand at only 20 years old was a key component of a side that won La Liga and the European Cup. Juegos de casino para windows 8 the beginning of the —06 seasonBayern has played its home games at the Allianz Arena. This may be due to Guardiola having faith in his players to recognise spaces formel eins sonntag the match and their ability to move around their opponents. Guardiola adjusted immediately, as Basketball schalke had suspected he would, and when he moved to the first-team inhe became the pivot of the Dream Team. De Bruyne will then ginter freiburg good patience to wait for the pass as it arrives from an improbable source, using the newfound space to dribble into or thread 7 wonders spiel balls in behind onto oncoming runners. Between andhe played seven friendly games for Catalonia. His wild casino in Italy, however, was unsuccessful and included a four-month ban for testing positive handy online aufladen paypal nandrolone. A frequent manner in which City progress up the field takes advantage of the quality found in on the wings. Josep Guardiola Sala —99". Als Neunter landete er mit Brescia nur einen Platz hinter der Roma, war aber im Tabellenmittelfeld trotzdem lediglich vier Punkte von einem Abstiegsplatz entfernt. Retrieved 14 August Josep Guardiola Sala —96". CE January 3, um 7: Guardiola employed this system australian online casino microgaming a 5—0 win against Villarreal with Javier Mascherano, Sergio Busquets and Rue de clichy casino de paris Abidal as the back-three and Seydou Keita acting as a defensive midfield.
Maradona zurück in Mexiko ran. Ganz wichtig war auch Juan Manuel Lillo. Nun steht das Team des Jahres Ich habe sechs Jahre unter ihm arbeiten können, und er hat mir viel beigebracht. Ich schätze ihn sehr und bin ihm sehr dankbar.


text:
require "active_support/all"
require "aws-sdk"
require "base64"
require "fileutils"
require "git"
require "netaddr"
require "thor/group"

module Shiprails
  class Ship < Thor
    class Setup < Thor::Group
      include Thor::Actions

      class_option "path",
        aliases: ["-p"],
        default: ".",
        desc: "Specify a configuration path"

      def create_cloudwatch_logs_group
        say "Creating CloudWatch Log groups..."
        created_groups = []
        configuration[:services].each do |service_name, service|
          service[:regions].each do |region_name, region|
            client = Aws::CloudWatchLogs::Client.new(region: region_name.to_s)
            region[:environments].each do |environment_name|
              cluster_name = "#{project_name}_#{environment_name}"
              unless created_groups.include? cluster_name
                begin
                  client.create_log_group({ log_group_name: cluster_name })
                rescue Aws::CloudWatchLogs::Errors::ResourceAlreadyExistsException => err
                end
                say "Created #{cluster_name} log group."
                created_groups << cluster_name
              end
            end
          end
        end
        say "Created CloudWatch Log groups.", :green
      end

      def create_vpcs
        say "Creating VPCs..."
        created_vpcs = []
        configuration[:services].each do |service_name, service|
          service[:regions].each do |region_name, region|
            ec2 = Aws::EC2::Client.new region: region_name.to_s
            region[:environments].each do |environment_name|
              vpc_name = "#{project_name}_#{environment_name}"
              unless created_vpcs.include? vpc_name
                begin
                  vpcs = ec2.describe_vpcs.vpcs
                  vpc = vpcs.find{ |v| v.tags.find{|t| t.key == "Name" }.try(:value) == vpc_name }
                  unless vpc.nil?
                    say "Found #{vpc_name}."
                    next
                  end
                  say "Setting up #{vpc_name}."
                  vpc_cidr_block = "10.0.0.0/16"
                  vpc = ec2.create_vpc({
                    amazon_provided_ipv_6_cidr_block: true,
                    cidr_block: vpc_cidr_block,
                  }).vpc
                  vpc = Aws::EC2::Vpc.new client: ec2, id: vpc.vpc_id
                  vpc.modify_attribute({
                    enable_dns_support: { value: true }
                  })
                  vpc.create_tags({ tags: [{ key: 'Name', value: vpc_name }]})
                  availability_zones = ec2.describe_availability_zones({
                    filters: [{
                      name: "state",
                      values: ["available"]
                    }]
                  }).availability_zones
                  say "Creating #{availability_zones.length} availability zones."
                  bits = 16
                  while true
                    begin
                      NetAddr::CIDR.create(vpc_cidr_block).subnet(:Bits => bits, :NumSubnets => availability_zones.count)
                    rescue
                      bits += 1
                      retry if bits <= 32
                    end
                    break
                  end
                  cidr_blocks = NetAddr::CIDR.create(vpc_cidr_block).subnet(:Bits => bits, :NumSubnets => availability_zones.count)
                  v6_cidr_blocks = NetAddr::CIDR.create(vpc.ipv_6_cidr_block_association_set.first.ipv_6_cidr_block).subnet(:Bits => 64, :NumSubnets => availability_zones.count)
                  availability_zones.each_with_index do |zone, idx|
                    ec2.create_subnet({
                      vpc_id: vpc.vpc_id,
                      cidr_block: cidr_blocks[idx],
                      ipv_6_cidr_block: v6_cidr_blocks[idx],
                      availability_zone: zone.zone_name,
                    })
                    say "Created subnet for #{zone.zone_name} availability zone (#{vpc_name})."
                  end
                  ig = ec2.create_internet_gateway.internet_gateway
                  ec2.attach_internet_gateway({
                    internet_gateway_id: ig.internet_gateway_id,
                    vpc_id: vpc.vpc_id,
                  })
                  say "Created internet gateway for #{vpc_name}."
                  route_table = ec2.create_route_table({
                    vpc_id: vpc.vpc_id,
                  }).route_table
                  say "Created route table for #{vpc_name}."
                  ec2.create_route({
                    destination_cidr_block: "0.0.0.0/0",
                    gateway_id: ig.internet_gateway_id,
                    route_table_id: route_table.route_table_id,
                  })
                  ec2.create_route({
                    destination_cidr_block: "::/0",
                    gateway_id: ig.internet_gateway_id,
                    route_table_id: route_table.route_table_id,
                  })
                # rescue Aws::IAM::Errors::EntityAlreadyExists => err
                end
                say "Created #{vpc_name} VPC."
                created_vpcs << vpc_name
              end
            end
          end
        end
        say "Created VPCs.", :green
      end

      def create_security_groups
        say "Creating security groups..."
        completed_vpcs = []
        configuration[:services].each do |service_name, service|
          service[:regions].each do |region_name, region|
            ec2 = Aws::EC2::Client.new region: region_name.to_s
            region[:environments].each do |environment_name|
              vpc_name = "#{project_name}_#{environment_name}"
              unless completed_vpcs.include? vpc_name
                begin
                  vpcs = ec2.describe_vpcs.vpcs
                  vpc = vpcs.find{ |v| v.tags.find{|t| t.key == "Name" }.try(:value) == vpc_name }
                  ecs_security_group_id = ec2.create_security_group({
                    group_name: "ecs-#{vpc_name}",
                    description: "ECS cluster instances",
                    vpc_id: vpc.vpc_id
                  }).group_id
                  ecs_security_group = Aws::EC2::SecurityGroup.new(client: ec2, id: ecs_security_group_id)
                  elb_security_group_id = ec2.create_security_group({
                    group_name: "elb-#{vpc_name}",
                    description: "ELB instances",
                    vpc_id: vpc.vpc_id
                  }).group_id
                  elb_security_group = Aws::EC2::SecurityGroup.new(client: ec2, id: elb_security_group_id)
                  public_web_security_group_id = ec2.create_security_group({
                    group_name: "public-web-#{vpc_name}",
                    description: "Public web ingress",
                    vpc_id: vpc.vpc_id
                  }).group_id
                  public_web_security_group = Aws::EC2::SecurityGroup.new(client: ec2, id: public_web_security_group_id)
                  datastores_security_group_id = ec2.create_security_group({
                    group_name: "datastores-#{vpc_name}",
                    description: "RDS, ElastiCache, etc. instances",
                    vpc_id: vpc.vpc_id
                  }).group_id
                  datastores_security_group = Aws::EC2::SecurityGroup.new(client: ec2, id: datastores_security_group_id)
                  team_access_security_group_id = ec2.create_security_group({
                    group_name: "team-access-#{vpc_name}",
                    description: "Ingress for team members",
                    vpc_id: vpc.vpc_id
                  }).group_id
                  team_access_security_group = Aws::EC2::SecurityGroup.new(client: ec2, id: team_access_security_group_id)
                  # allow ECS instances to receive traffic from ELBs
                  ecs_security_group.authorize_ingress({
                    ip_permissions: [
                      {
                        from_port: "-1",
                        to_port: "-1",
                        ip_protocol: "-1",
                        user_id_group_pairs: [{
                          group_id: elb_security_group.id,
                          vpc_id: vpc.vpc_id,
                        }],
                      }
                    ]
                  })
                  # allow public web group to receive traffic from the web
                  ec2.authorize_security_group_ingress({
                    group_id: public_web_security_group_id,
                    ip_permissions: [
                      {
                        from_port: "80",
                        ip_ranges: [{
                          cidr_ip: "0.0.0.0/0"
                        }],
                        to_port: "80",
                        ip_protocol: "tcp",
                        ipv_6_ranges: [{
                          cidr_ipv_6: "::/0"
                        }]
                      },
                      {
                        from_port: "443",
                        ip_ranges: [{
                          cidr_ip: "0.0.0.0/0"
                        }],
                        to_port: "443",
                        ip_protocol: "-1",
                        ipv_6_ranges: [{
                          cidr_ipv_6: "::/0"
                        }]
                      },
                    ]
                  })
                  # allow datastore instances to receive traffic from ECS instances
                  current_ip_address = open('http://whatismyip.akamai.com').read
                  ec2.authorize_security_group_ingress({
                    group_id: team_access_security_group_id,
                    ip_permissions: [
                      {
                        from_port: "-1",
                        ip_ranges: [{
                          cidr_ip: "#{current_ip_address}/32"
                        }],
                        to_port: "-1",
                        ip_protocol: "-1",
                      },
                    ]
                  })
                  # allow ELBs to access ECS instances
                  elb_security_group.authorize_egress({
                    ip_permissions: [
                      {
                        from_port: "-1",
                        to_port: "-1",
                        ip_protocol: "-1",
                        user_id_group_pairs: [{
                          group_id: ecs_security_group.id,
                          vpc_id: vpc.vpc_id,
                        }],
                      }
                    ]
                  })
                rescue Aws::EC2::Errors::InvalidGroupDuplicate => err
                  say "Security groups for #{vpc_name} VPC already setup."
                end
                say "Created security groups for #{vpc_name} VPC."
                completed_vpcs << vpc_name
              end
            end
          end
        end
        say "Created security groups..", :green
      end

      def create_key_pairs
        say "Creating EC2 key pairs..."
        created_key_pairs = []
        configuration[:services].each do |service_name, service|
          service[:regions].each do |region_name, region|
            region[:environments].each do |environment_name|
              key_pair_name = "#{project_name}"
              unless created_key_pairs.include? key_pair_name
                begin
                  ec2 = Aws::EC2::Client.new(region: region_name.to_s)
                  key_pair = ec2.create_key_pair({
                    key_name: key_pair_name
                  })
                  File.open("#{project_name}.pem", 'w') { |file| file.write(key_pair.key_material) }
                  FileUtils.chmod 0600, "#{project_name}.pem"
                rescue Aws::EC2::Errors::InvalidKeyPairDuplicate => err
                  say "Key pair #{project_name} already exists."
                end
                created_key_pairs << key_pair_name
              end
            end
          end
        end
        say "Created EC2 key pairs.", :green
      end

      def create_ecs_autoscale_role
        say "Creating ECS AutoScaling IAM roles..."
        iam = Aws::IAM::Client.new
        created_roles = []
        configuration[:services].each do |service_name, service|
          service[:regions].each do |region_name, region|
            region[:environments].each do |environment_name|
              role_name = "#{project_name}_#{environment_name}-ecsAutoScaling"
              unless created_roles.include? role_name
                begin
                  role = iam.create_role({
                    assume_role_policy_document: "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"application-autoscaling.amazonaws.com\"]},\"Action\":[\"sts:AssumeRole\"]}]}",
                    path: "/",
                    role_name: role_name,
                  })
                  iam.attach_role_policy({
                    policy_arn: "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRole",
                    role_name: role_name,
                  })
                rescue Aws::IAM::Errors::EntityAlreadyExists => err
                end
                say "Created #{role_name} IAM role."
                created_roles << role_name
              end
            end
          end
        end
        say "Created ECS AutoScaling IAM roles.", :green
      end

      def create_ecs_instance_role
        say "Creating ECS EC2 Instance IAM roles..."
        iam = Aws::IAM::Client.new
        created_roles = []
        configuration[:services].each do |service_name, service|
          service[:regions].each do |region_name, region|
            region[:environments].each do |environment_name|
              role_name = "#{project_name}_#{environment_name}-ecsInstanceRole"
              unless created_roles.include? role_name
                begin
                  role = iam.create_role({
                    assume_role_policy_document: "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"ec2.amazonaws.com\"]},\"Action\":[\"sts:AssumeRole\"]}]}",
                    path: "/",
                    role_name: role_name,
                  })
                  iam.create_instance_profile({
                    instance_profile_name: role_name,
                  })
                  iam.add_role_to_instance_profile({
                    instance_profile_name: role_name,
                    role_name: role_name,
                  })
                  iam.attach_role_policy({
                    policy_arn: "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role",
                    role_name: role_name,
                  })
                  iam.put_role_policy({
                    policy_document: "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"logs:CreateLogGroup\",\"logs:CreateLogStream\",\"logs:DescribeLogGroups\",\"logs:DescribeLogStreams\",\"logs:PutLogEvents\"],\"Effect\":\"Allow\",\"Resource\":\"arn:aws:logs:#{region_name.to_s}:#{aws_account_number}:log-group:#{project_name}_#{environment_name}\"}]}",
                    policy_name: "ecs-cloudwatch-logs",
                    role_name: role_name,
                  })
                  iam.put_role_policy({
                    policy_document: "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":[\"ecs:DescribeTasks\",\"ecs:ListContainerInstances\",\"ecs:ListTasks\",\"ecs:StartTask\",\"ecs:StopTask\"],\"Resource\":\"arn:aws:ecs:#{region_name.to_s}:#{aws_account_number}:cluster/#{project_name}_#{environment_name}\"}]}",
                    policy_name: "ecs-tasks",
                    role_name: role_name,
                  })
                  iam.put_role_policy({
                    policy_document: "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"Stmt1492034037000\",\"Effect\":\"Allow\",\"Action\":[\"s3:Get*\"],\"Resource\":[\"arn:aws:s3:::#{project_name}-config/#{environment_name}/*\"]}]}",
                    policy_name: "read-config-from-s3",
                    role_name: role_name,
                  })
                rescue Aws::IAM::Errors::EntityAlreadyExists => err
                end
                say "Created #{role_name} IAM role."
                created_roles << role_name
              end
            end
          end
        end
        say "Created ECS EC2 Instance IAM roles.", :green
      end

      def create_ecs_task_role
        say "Creating ECS Task IAM roles..."
        iam = Aws::IAM::Client.new
        created_roles = []
        configuration[:services].each do |service_name, service|
          service[:regions].each do |region_name, region|
            region[:environments].each do |environment_name|
              role_name = "#{project_name}_#{environment_name}-ecs-task"
              unless created_roles.include? role_name
                begin
                  role = iam.create_role({
                    assume_role_policy_document: "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"ecs-tasks.amazonaws.com\"]},\"Action\":[\"sts:AssumeRole\"]}]}",
                    path: "/",
                    role_name: role_name,
                  })
                  iam.put_role_policy({
                    policy_document: "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"Stmt1492034037000\",\"Effect\":\"Allow\",\"Action\":[\"s3:Get*\"],\"Resource\":[\"arn:aws:s3:::#{project_name}-config/#{environment_name}/*\"]}]}",
                    policy_name: "read-config-from-s3",
                    role_name: role_name,
                  })
                rescue Aws::IAM::Errors::EntityAlreadyExists => err
                end
                say "Created #{role_name} IAM role."
                created_roles << role_name
              end
            end
          end
        end
        say "Created ECS Task IAM roles.", :green
      end

      def create_ecs_tasks
        say "Creating ECS tasks..."
        configuration[:services].each do |service_name, service|
          image_name = "#{project_name}_#{service_name}"
          service[:regions].each do |region_name, region|
            ecs = Aws::ECS::Client.new(region: region_name.to_s)
            region[:environments].each do |environment_name|
              cluster_name = "#{project_name}_#{environment_name}"
              task_name = "#{image_name}_#{environment_name}"
              begin
                task_definition_description = ecs.describe_task_definition({task_definition: task_name})
                task_definition = task_definition_description.task_definition.to_hash
                task_definition.delete :task_definition_arn
                task_definition.delete :revision
                task_definition.delete :status
                task_definition.delete :requires_attributes
                say "Updating ECS task (#{task_name})."
              rescue Aws::ECS::Errors::ClientException => e
                task_definition = {
                  container_definitions: [
                    {
                      command: [service[:command]],
                      cpu: service[:resources][:cpu_units],
                      essential: true,
                      environment: [
                        { name: "AWS_REGION", value: region_name.to_s },
                        { name: "RACK_ENV", value: environment_name },
                        { name: "S3_CONFIG_BUCKET", value: config_s3_bucket },
                        { name: "S3_CONFIG_ENVIRONMENT", value: environment_name },
                        { name: "S3_CONFIG_REVISION", value: "0" }
                      ],
                      image: "#{region[:repository_url]}:latest",
                      log_configuration: {
                        log_driver: "awslogs",
                        options: {
                          "awslogs-group" => cluster_name,
                          "awslogs-region" => region_name.to_s,
                          "awslogs-stream-prefix" => service_name
                        }
                      },
                      memory: service[:resources][:memory_units],
                      name: service_name,
                      port_mappings: (service[:ports] || []).map { |port|
                        {
                          container_port: port,
                          host_port: 0,
                          protocol: "tcp"
                        }
                      }
                    }
                  ],
                  family: task_name,
                  task_role_arn: "arn:aws:iam::#{aws_account_number}:role/#{project_name}_#{environment_name}-ecs-task"
                }
                say "Creating new ECS task (#{task_name})!"
              end
              task_definition_response = ecs.register_task_definition(task_definition)
            end
          end
        end
        say "Created ECS tasks!", :green
      end

      def create_ecs_clusters
        say "Creating ECS clusters..."
        cluster_names = []
        configuration[:services].each do |service_name, service|
          image_name = "#{project_name}_#{service_name}"
          service[:regions].each do |region_name, region|
            ecs = Aws::ECS::Client.new(region: region_name.to_s)
            region[:environments].each do |environment_name|
              cluster_name = "#{project_name}_#{environment_name}"
              next if cluster_names.include? cluster_name
              cluster_names << cluster_name
              ecs.create_cluster({
                cluster_name: cluster_name
              })
              say "Created ECS cluster (#{cluster_name})!"
            end
          end
        end
        say "Created ECS clusters!", :green
      end

      def create_ec2_launch_configurations
        say "Creating EC2 LaunchConfigurations..."
        autoscaling = Aws::AutoScaling::Client.new
        created_launch_configurations = []
        configuration[:services].each do |service_name, service|
          service[:regions].each do |region_name, region|
            region[:environments].each do |environment_name|
              launch_configuration_name = "#{project_name}_#{environment_name}-v1"
              unless created_launch_configurations.include? launch_configuration_name
                begin
                  ec2 = Aws::EC2::Client.new(region: region_name.to_s)
                  images = ec2.describe_images({
                    filters: [
                      {
                        name: 'name',
                        values: ['amzn-ami-201*-amazon-ecs-optimized']
                      },
                      {
                        name: 'owner-alias',
                        values: ['amazon']
                      },
                      {
                        name: 'state',
                        values: ['available']
                      },
                    ],
                  }).images
                  image = images.sort_by(&:name).last # get the newest version
                  vpcs = ec2.describe_vpcs.vpcs
                  vpc = vpcs.find{ |v| v.tags.find{|t| t.key == "Name" }.try(:value) == "#{project_name}_#{environment_name}" }
                  security_groups = ec2.describe_security_groups({
                    filters: [
                      {
                        name: "vpc-id",
                        values: [
                          vpc.vpc_id
                        ],
                      },
                    ],
                  }).security_groups
                  security_group = security_groups.find{ |group| group.group_name == "ecs-#{project_name}_#{environment_name}" }
                  autoscaling.create_launch_configuration({
                    block_device_mappings: [
                      {
                        device_name: "/dev/xvdcz",
                        ebs: {
                          delete_on_termination: true,
                          encrypted: false,
                          volume_size: 22,
                          volume_type: "gp2",
                        },
                      },
                    ],
                    iam_instance_profile: "#{project_name}_#{environment_name}-ecsInstanceRole",
                    image_id: image.image_id,
                    instance_type: "t2.small",
                    key_name: "#{project_name}",
                    launch_configuration_name: launch_configuration_name,
                    security_groups: [ security_group.group_id ],
                    user_data: Base64.encode64("#!/bin/bash
echo ECS_CLUSTER=#{project_name}_#{environment_name} >> /etc/ecs/ecs.config"),
                  })
                rescue Aws::AutoScaling::Errors::AlreadyExists
                  say "TODO: update LaunchConfiguration with latest stuff.", :blue
                end
                created_launch_configurations << launch_configuration_name
              end
            end
          end
        end
        say "Created EC2 LaunchConfigurations!", :green
      end

      def create_ec2_autoscaling_groups
        say "Creating EC2 AutoScaling Groups..."
        autoscaling = Aws::AutoScaling::Client.new
        created_auto_scaling_groups = []
        configuration[:services].each do |service_name, service|
          service[:regions].each do |region_name, region|
            region[:environments].each do |environment_name|
              group_name = "#{project_name}_#{environment_name}"
              unless created_auto_scaling_groups.include? group_name
                ec2 = Aws::EC2::Client.new region: region_name.to_s
                vpcs = ec2.describe_vpcs.vpcs
                vpc = vpcs.find{ |v| v.tags.find{|t| t.key == "Name" }.try(:value) == "#{project_name}_#{environment_name}" }
                subnets = ec2.describe_subnets({
                  filters: [
                    {
                      name: "vpc-id",
                      values: [
                        vpc.vpc_id
                      ],
                    },
                  ],
                }).subnets
                zones_in_region = subnets.map(&:availability_zone)
                subnets_in_region = subnets.map(&:subnet_id)
                begin
                  autoscaling.create_auto_scaling_group({
                    auto_scaling_group_name: group_name,
                    availability_zones: zones_in_region,
                    default_cooldown: 300,
                    health_check_grace_period: 300,
                    health_check_type: "EC2",
                    launch_configuration_name: "#{project_name}_#{environment_name}-v1",
                    max_size: 10,
                    min_size: 1,
                    vpc_zone_identifier: subnets_in_region.join(',')
                  })
                rescue Aws::AutoScaling::Errors::AlreadyExists
                  say "TODO: update AutoScaling Group with latest stuff like LaunchConfiguration name.", :blue
                end
                created_auto_scaling_groups << group_name
              end
            end
          end
        end
        say "Created EC2 LaunchConfigurations!", :green
      end

      def create_ecs_services
        say "Creating ECS services..."
        configuration[:services].each do |service_name, service|
          image_name = "#{project_name}_#{service_name}"
          service[:regions].each do |region_name, region|
            ecs = Aws::ECS::Client.new(region: region_name.to_s)
            elb = Aws::ElasticLoadBalancingV2::Client.new(region: region_name.to_s)
            region[:environments].each do |environment_name|
              role_name = "#{project_name}_#{environment_name}-ecsServiceRole"
              iam = Aws::IAM::Client.new
              begin
                role = iam.create_role({
                  assume_role_policy_document: "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"ecs.amazonaws.com\"]},\"Action\":[\"sts:AssumeRole\"]}]}",
                  path: "/",
                  role_name: role_name,
                })
                iam.attach_role_policy({
                  policy_arn: "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole",
                  role_name: role_name,
                })
                say "Created ECS Service role..."
              rescue Aws::IAM::Errors::EntityAlreadyExists => err
              end

              cluster_name = "#{project_name}_#{environment_name}"
              task_name = "#{image_name}_#{environment_name}"
              task_definition_response = ecs.describe_task_definition({task_definition: task_name})
              task_definition = task_definition_response.task_definition.to_hash
              ecs_service = {
                cluster: cluster_name,
                deployment_configuration: {
                  maximum_percent: 200,
                  minimum_healthy_percent: 50,
                },
                desired_count: 0,
                service_name: service_name,
                task_definition: task_definition_response.task_definition.task_definition_arn
              }
              (service[:ports] || []).each do |port|
                if yes? "Should port #{port} for #{image_name} be load balanced in #{environment_name}?"
                  ecs_service[:role] = role_name
                  load_balancers = elb.describe_load_balancers.to_h
                  say "EC2 Load Balancers"
                  choices = ["CREATE NEW ELB"] + load_balancers[:load_balancers].map{|lb| "#{lb[:load_balancer_name]} (#{lb[:load_balancer_arn]})" }
                  choices = choices.map.with_index{ |a, i| [i+1, *a]}
                  print_table choices
                  selection = ask("Pick one:").to_i
                  if selection == 1
                    say "Creating new ELB not yet supported.", :red
                    say "Create a new ELB in your console.", :red
                    say "Then, run `ship setup` again.", :red
                    exit
                  else
                    load_balancer = load_balancers[:load_balancers][selection - 2]
                  end
                  say "Selected: #{load_balancer[:load_balancer_name]}"
                  target_group_name = "#{project_name}-#{service_name}-#{environment_name}"
                  target_group_resp = elb.create_target_group({
                    name: target_group_name,
                    port: port,
                    protocol: "HTTP",
                    vpc_id: load_balancer[:vpc_id]
                  }).to_h
                  target_group_arn = target_group_resp[:target_groups][0][:target_group_arn]
                  say "Created target group: #{target_group_name}."
                  ecs_service[:load_balancers] = [
                    {
                      container_name: service_name,
                      container_port: port,
                      target_group_arn: target_group_arn
                    }
                  ]
                end
              end
              begin
                service_response = ecs.create_service(ecs_service)
                say "Created ECS service (#{service_name})!"
              rescue Aws::ECS::Errors::InvalidParameterException => e
                case e.message
                when "Creation of service was not idempotent."
                  say "Service #{service_name} already exists.", :yellow
                  say "If you've changed load balancers setup, you must delete the existing service.", :yellow
                when /The target group with targetGroupArn ([^\s\\]+) does not have an associated load balancer./
                  say "Link Target Group to Load Balancer", :red
                  say "Visit `https://#{region_name}.console.aws.amazon.com/ec2/v2/home?region=#{region_name}#LoadBalancers:`", :red
                  say "Add listener for Target Group (#{$1})", :red
                else
                  raise e
                end
              end
            end
          end
        end
        say "Created ECS services!", :green
      end

      def create_cloudwatch_ecs_alarms
        say "TODO: create cloudwatch alarms for cluster memory", :blue
      end

      def create_cloudwatch_elb_alarms
        say "TODO: create cloudwatch alarms for elb latency / service units", :blue
      end

      def create_iam_groups
        say "TODO: create cloudwatch logs read group", :blue
        say "TODO: create scale group", :blue
        say "TODO: create deploy IAM group", :blue
        say "TODO: create run task IAM group", :blue
        say "TODO: create exec interactive IAM group", :blue
      end

      private

      def aws_access_key_id
        @aws_access_key_id ||= ask "AWS Access Key ID", default: ENV.fetch("AWS_ACCESS_KEY_ID")
      end

      def aws_access_key_secret
        @aws_access_key_secret ||= ask "AWS Access Key Secret", default: ENV.fetch("AWS_SECRET_ACCESS_KEY")
      end

      def aws_account_number
        @aws_account_number ||= Aws::STS::Client.new().get_caller_identity.account
      end

      def configuration
        YAML.load(File.read("#{options[:path]}/.shiprails.yml")).deep_symbolize_keys
      end

      def project_name
        configuration[:project_name]
      end

      def config_s3_bucket
        configuration[:config_s3_bucket]
      end

    end
  end
end

redpajama_set_name: RedPajamaGithub